非常详细的Python字典高级用法介绍(一)

本文介绍了Python字典的高级用法,包括字典推导式创建字典、映射拆包优雅传参、使用|运算符合并映射、defaultdict处理缺失键等,展示了Python字典的灵活性和高效性。
摘要由CSDN通过智能技术生成

没有Python程序不使用字典,即使不直接出现在我们编写的代码中,我们也会间接的用到,因为字典dict是实现Python的基石,也可以说Python就是包裹在一堆语法糖中的字典。由于字典的关键作用,Python对字典做了高度优化,并且在持续改进,Python字典之所以高效,要归功于哈希表。除了字典以外,内置类型中的set和frozenset也是基于哈希表。这两种类型的API和运算符比其他流行语言的集合更加丰富。接下来就开始字典常见的高级用法介绍

1、字典推导式

自Python2.7开始,列表推导式和生成器表达经过改成以适应字典推导式,字典推导式可以从可迭代对象中获取键值对,构建dict实例。

citys = [
    (3, 'shanghai'), (1, 'beijing'), (4, 'shanghai'),
    (2, 'shenzhen'), (6, 'wuhan'), (5, 'tianjin'), (7, 'chengdu')
]

idx_city_dict = {idx: city for idx, city in citys}  # 使用推导式构建dict
print(idx_city_dict)  # {3: 'shanghai', 1: 'beijing', 4: 'shanghai', 2: 'shenzhen', 6: 'wuhan', 5: 'tianjin', 7: 'chengdu'}
#使用推导式根据条件生成dict,将上面字典按照idx排序,将键值对位置对调,city转换成大写,筛选出idx大于3的数据
city_id_dict = {city.upper(): idx for idx, city in sorted(idx_city_dict.items()) if idx >3}
print(city_id_dict)  # {'SHANGHAI': 4, 'TIANJIN': 5, 'WUHAN': 6, 'CHENGDU': 7}

2、映射拆包

个人觉得,字典的映射拆包是一种很优雅的传参方式。首先,不止一个参数可以使用**。所有键都要是字符串,而且在所有参数中是唯一的(因为关键字参数不可重复)

def dump(**kwargs):
    return kwargs

res = dump(**{'x': 11}, y=22, **{'z': 33})
print(res)  # {'x': 11, 'y': 22, 'z': 33}
# **还可以在字典字面量里面使用。同时可以使用多次,这种情况可以重复键,因为后面的键会覆盖前面的键
a_map = {'a': 0, **{'x': 11}, 'y': 22, **{'z': 33, 'x': 44}}
print(dump(**a_map))  # {'a': 0, 'x': 44, 'y': 22, 'z': 33}

3、使用 | 合并映射

python3.9支持使用 | 和 |=合并映射,其实就是并集运算符。| 运算符创建一个新映射。

a = {'a': 11, 'b': 22, 'c': 33}
b = {'x': 44, 'y': 55, 'z': 66}
a_b = a | b
print(a_b)  # {'a': 11, 'b': 22, 'c': 33, 'x': 44, 'y': 55, 'z': 66}

如果想就地更新现有映射,则使用 |=

a |= b
print(a)  # a变了 {'a': 11, 'b': 22, 'c': 33, 'x': 44, 'y': 55, 'z': 66}
print(b)  # b没变 {'x': 44, 'y': 55, 'z': 66}

4、映射类型的标准API

如果想⾃定义映射类型,扩展 collections.UserDict 或通过组合 模式包装 dict 更简单,那就不要定义这些抽象基类的子类。 collections.UserDict 类和标准库中的所有具体映射类都在实现中封装了基本的 dict,而 dict 又建立在哈希表之上。因此,这些类有一个共同的限制,即键必须可哈希(值不要求可哈希,只有键需要)。

“可哈希”指什么:“可哈希”在Python术语表中有定义,即如果⼀个对象的哈希码在整个⽣命周期内永不改变(依托 __hash__() ⽅法),而且可与其他对象比较(依托 __eq__() ⽅法),那么这个对象就是可哈希的。两个可哈希对象仅当哈希 码相同时相等。

数值类型以及不可变的扁平类型str和bytes均是可哈希的,如果容器类型是不可变的,而且所含的对象全是可哈希的,那么容器类型自身也是可哈希的。frozenset对象全是可哈希的,因为按照定义,每一个元素都必须是可哈希的。仅当所有项均可哈希,元组对象才是可哈希的。

常用的映射方法

 dictdefaultdictorderedDict 
d.clear()删除所有项
d.__contains__(k)k in d
d.copy()浅拷⻉
d.__copy__()  为 copy.copy(d) 提供⽀持
d.default_factory  由 __missing__ 调⽤的可调⽤ 对象,⽤于设置缺失的值
d.__delitem__(k)del d[k]:删除键 k 对应的项
d.fromkeys(it, [initial])根据可迭代对象中的键构建⼀ 个映射,可选参数 initial 指 定初始值(默认为 None)
d.get(k, [default])获取键 k 对应的项,不存在时 返回 default 或 None
d.__getitem__(k)d[k]:获取键 k 对应的项
d.items()获取项视图,即 (key, value) 对
d.__iter__()获取遍历键的迭代器
d.keys()获取键视图
d.__len__()len(d):项数
d.__missing__(k)  当 __getitem__ 找不到相应的 键时调⽤
d.move_to_end(k, [last])  把 k 移到开头或结尾(last 默 认为 True)
d.__or__(other)d1 | d2:合并 d1 和 d2,新建 ⼀个 dict 对象(Python 3.9 及 以上版本)
d.__ior__(other)d1 |= d2:使⽤ d2 中的项更 新 d1(Python 3.9 及以上版 本)
d.pop(k, [default])删除并返回 k 对应的项,如果 没有键 k,则返回 default 或 None
d.popitem()删除并返回((key, value) 形 式)最后插⼊的项
d.__reversed__()reverse(d):按插⼊顺序从后 向前返回遍历键的迭代器
d.__ror__(other)other | dd:反向合并运算符 (Python 3.9 及以上版本)
d.setdefault(k, [default])如果 d 中有键 k,则返回 d[k];否则,把 d[k] 设为 default,并返回 default
d.__setitem__(k, v)d[k] = v:把键 k 对应的值设 为 v
d.update(m, [**kwargs])使⽤映射或可迭代对象中的键 值对更新
d.values()获取值视图

5、插入或者更新可变的值

根据Python的“快速失败”原则,当键k不存在时,d[k]抛出错误,熟悉Python的人知道,如果不想抛出KeyError错误,而是想提供一个默认值,可以把d[k]换成d.get(k,default)。然而,如果你想更新得到的可变值,那么还有更好的方法。

比如下面这个案例,统计一段文本中每个字出现在文本的中的位置

text = "山川连绵川流不息川流汇成江海海纳百川川流不息川流汇聚成大江大河江河湖海海阔天空川流不息川流汇聚汇聚成海海纳百川川流不息"
index = {}
for i in range(len(text)):
    word = text[i]
    d = index.get(word, [])
    d.append(i + 1)
    index[word] = d
print(index)
# {'山': [1], '川': [2, 5, 9, 18, 19, 23, 40, 44, 55, 56], '连': [3], '绵': [4], '流': [6, 10, 20, 24, 41, 45, 57],
# '不': [7, 21, 42, 58], '息': [8, 22, 43, 59], '汇': [11, 25, 46, 48],
# '成': [12, 27, 50], '江': [13, 29, 32], '海': [14, 15, 35, 36, 51, 52], '纳': [16, 53], '百': [17, 54],
# '聚': [26, 47, 49], '大': [28, 30], '河': [31, 33], '湖': [34], '阔': [37], '天': [38], '空': [39]}

当然也可以这样写,效果也是一样的

index = {}
for i in range(len(text)):
    word = text[i]
    if word not in index:
        index[word] = []
    index[word].append(i + 1)
print(index)

但是换成dict.setdefault()则只需一行代码就搞定了

index = {}
for i in range(len(text)):
    word = text[i]
    index.setdefault(word,[]).append(i+1)
print(index)

index.setdefault(word,[]).append(i+1)获取word出现的位置,如果没有找到,则设为[];setdefault返回该列表,可以直接更新,不用再搜索一次,作用与上面的示例一样,只不过上面的示例至少要搜索两次key,如果没有找到则搜索三次,而setdefault只搜索一次。

6、自动处理缺少的键

有时搜索的键不一定存在,为了以防万一,可以人为设置一个值,以方便某些情况的处理。人为设置的值主要有两种方法:第一种是把普通的dict换成defaultdict;第二种是定义dict或其他映射类型的子类,实现__miss__方法。下面我们主要介绍第一种方法把普通的dict换成defaultdict,第二种方法后续再讲。

defaultdict处理缺失键的实现原理就是,实例化defaultdict对象时提供一个可调用对象,当__getitem__遇到不存在的键时,调用那个可调用对象生成一个默认值。

比如使用dd=defaultdict(list)创建一个defaultdict对象,而且dd中没有'new_key'键,那么dd['new_key']表达式按以下几步进行处理。

  1. 调用list()创建一个新列表
  2. 把该列表插入dd,对应到'new_key'键上
  3. 返回该列表的作用

与上述的dict.setdefault有异曲同工之妙,直接看代码

index = collections.defaultdict(list)  # 创建一个defaultdict对象,把default_factory设为list构造函数
for i in range(len(text)):
    word = text[i]
    # 如果index里面没有word键,调用default_factory生成缺少的值,这里生成一个列表,赋值给index[word],然后返回一个空列表,因此append操作一种有效。
    # 如果没提供default_factory,遇到键缺失还是会抛出KeyError错误
    index[word].append(i + 1)
print(index)

字典的高级用法一就先到这里了,感兴趣的可以帮忙点个关注和赞,后续还会继续更新字典的用法哈。

 

 

  • 16
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当然,我很乐意为您提供关于Python详细介绍。以下是关于Python的文档: Python是一种高级编程语言,由 Guido van Rossum 于1991年创建。Python以其简洁、易读和可扩展性而闻名,并且在不同领域的软件开发中得到广泛应用。 1. Python的特点: - 简洁易读:Python的语法设计简洁,代码易于阅读和理解,使得开发者能够快速上手。 - 动态类型:Python是一种动态类型语言,允许开发者在运行时灵活地创建、修改和使用变量。 - 面向对象:Python支持面向对象编程,提供了类、继承、多态等常见的面向对象特性。 - 大量的库和框架:Python拥有丰富的第三方库和框架,可以帮助开发者快速构建各种应用,如Web开发、数据分析、机器学习等。 2. Python的应用领域: - 网络开发Python有多个流行的Web框架,例如Django和Flask,可以用于构建高性能的Web应用程序。 - 数据科学和机器学习:Python拥有强大的数据处理和科学计算库(如NumPy、Pandas和SciPy),以及广泛应用于机器学习和人工智能的库(如Scikit-learn和TensorFlow)。 - 自动化和脚本编程:Python可以用于编写各种自动化脚本,如系统管理、任务调度、数据处理等。 - 游戏开发Python有一些专门用于游戏开发的库和框架,如Pygame和Pyglet。 - 桌面应用程序:Python可以用于构建跨平台的桌面应用程序,如使用Tkinter库进行图形界面开发。 - 科学计算和可视化:Python的数据处理和可视化库可以帮助科学家和研究人员进行数据分析、建模和可视化。 3. Python的基本语法: 以下是Python的一些基本语法特点: - 缩进:Python使用缩进来表示代码块,而不是使用大括号。这使得代码更加易读和简洁。 - 变量和数据类型:Python是动态类型语言,变量的类型由值来决定。Python支持多种内置的数据类型,如整数、浮点数、字符串、列表、元组、字典等。 - 条件和循环:Python提供了条件语句(如if-else语句)和循环语句(如for循环和while循环)来控制程序的执行流程。 - 函数和模块:Python支持函数的定义和调用,并且可以使用模块来组织代码。 - 异常处理:Python提供了异常处理机制,可以捕获和处理程序中的异常。 4. Python的学习资源: 如果您想学习Python,以下是一些推荐的学习资源: - 官方文档:Python官方网站提供了详细的文档,包括教程、指南和参考手册。您可以在https://docs.python.org/找到官方文档。 - 在线教程:有许多在线教程和课程可供选择,如Codecademy、Coursera、Udemy等。 - 书籍:有很多优秀的Python教材可供选择,如《Python编程快速上手》、《Python核心编程》等。 希望以上介绍能够对您对Python有更全面的了解。如果您有任何进一步的问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值