创建 dict 的几种方法学习小结
dict(全称 dictionary,可以翻译为“字典”),其使用“键-值(key-value)”对儿的方式存储多项数据,是一个无序可变的集合。
dict 的创建可以有多种方式:
1. 通过直接赋值方式创建
- 创建空字典
- 创建指定内容的字典
2. 使用 dict 关键字创建
- 创建空字典
- 通过传入关键字(**kwargs)方式创建
- 通过传入 映射(mapping)对象创建
- 通过传入可迭代(iterable)对象创建
3. 使用 fromkeys()
4. 使用 “生成式” 方法创建字典
1. 直接赋值创建
# 新建一个空白的字典
c1 = {}
# 新建一个指定内容的字典
c2 = {'name': 'Jonah', 'age': '14'}
2. 使用 dict 关键字创建
首先在 PyCharm 中打开 dict 类的说明(简单打开方法为:输入 dict 后,按下键盘 Ctrl 键,同时鼠标移动到 该关键字上方,待其样式变为超链后点击即可)。自动打开 builtins.py 文件的 dict 类定义位置,由于Python 的核心代码为C语言编写,此处是看不到真正源码的,但是我们可以看到其文档描述信息。
创建 dict 类的对象可以通过文档描述中的四种方式实现:
- dict(),创建空白的字典。
- dict(**kwargs),通过关键字参数方式创建。
- dict(mapping),通过传入映射类型对象方式创建。
- dict(iterable),通过传入可迭代对象方式创建。
文件:builtins.py
class dict(object):
def __init__(self, seq=None, **kwargs): # known special case of dict.__init__
"""
dict() -> new empty dictionary
dict(mapping) -> new dictionary initialized from a mapping object's
(key, value) pairs
dict(iterable) -> new dictionary initialized as if via:
d = {}
for k, v in iterable:
d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
in the keyword argument list. For example: dict(one=1, two=2)
# (copied from class doc)
"""
pass
另外,输入dict()后,按下 Ctrl键后,鼠标移动到此处并悬停后也会弹出相关提示信息。
(1) 创建空白的 dict
c1 = dict()
print(c1)
----------
输出: {}
(2) 通过关键字参数方式创建
分别把每个传入参数的名称作为字典的“键”,传入参数的值作为字典的“值”使用。
c1 = dict(name='Jonah', age=14)
print(c1)
-----------------------------
输出:{'name': 'Jonah', 'age': 14}
(3) 通过传入可迭代对象方式创建
我们知道,如列表、元组、字符串等都属于可迭代对象,可迭代对象的特点是其实现了__iter__方法,在使用 dict 关键字创建字典的时候,也可以传入一个可迭代的对象来实现。但是此对象中的每个元素都要求是包含两个对象的元组方式。
如: [('name', 'Jonah'), ('age', '14')]
或: {('name', 'Jonah'), ('age', '14')}
# 新建一个列表(list)类型的可迭代对象
it1 = [('name', 'Jonah'), ('age', '14')]
# 方法1:通过循环赋值的方式生成字典
dic1 = {}
for k, v in it1:
dic1[k] = v
print(dic1)
# 方法2:直接通过可迭代的对象生成字典
dic2 = dict(it1)
print(dic2)
------------------------
输出结果相同,二者是等价的,只是实现方法不同而已:
{'name': 'Jonah', 'age': '14'}
{'name': 'Jonah', 'age': '14'}
(4) 通过传入映射对象方式创建
通过“名称”来引用对应“值”的数据结构称为映射(mapping),dict 本身就是一种映射结构。所以可以直接将一个“字典”当作参数传入给另一个“字典”。
将一个“字典(dict)”以参数的方式传入另一个“字典(dict)”
# 先定义一个 dict1 备用
dic1 = {'name': 'Jonah', 'age': '14'}
# 1. 新建一个字典 dict,其参数中传入前面备用的 dic1
dic2 = dict(dic1)
print(dic2)
# 2. 新建一个字典 dict,传入:dic1 + 关键字参数
dic3 = dict(dic1, gender='男')
print(dic3)
---------------------------------
输出:
{'name': 'Jonah', 'age': '14'}
{'name': 'Jonah', 'age': '14', 'gender': '男'}
另外,Python 中还提供了 map 和 zip 相关的对象方法,以生成 mapping 对象,这类的 mapping 对象也可以当参数传入并生成 dict 对象。
- map():根据提供的函数对指定序列做映射。
- zip():将可迭代的对象作为参数,将其中对应的元素打包成多个元组,然后返回由这些元组组成的列表。
通过 map 方式创建字典
# 先定义一个函数,用于组合成一个“键值对”的映射关系
def f(k, v):
return (k, v)
# 定义两个可迭代对象,分别提供 “键值对” 里面的 “键” 和 “值”
lst = list('ABCDE')
num = range(1, 6)
# map方法,循环遍历两个可迭代对象,经过 f() 函数处理后,生成映射关系对象
m = map(f, lst, num)
# 将映射对象当作参数,生成字典
d = dict(m)
print(d)
====================
输出:{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5}
通过 zip 方式创建
# 定义两个可迭代对象
lst = list('ABCDE')
num = range(1, 6)
# 将二者一一对应,组成元组列表(存储了映射关系)
m = zip(lst,num)
# 新建字典
d = dict(m)
print(d)
====================
输出:{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5}
3. 通过fromkeys() 方法创建字典
fromkeys() 函数用于创建一个新字典,以第一个序列参数中的元素做字典的“键”,以第二个参数为字典所有键对应的初始“值”,相当于给字典中的所有键一个相同的初始值。
d1 = dict.fromkeys('ABCD', 0)
print(d1)
--------------------
输出:{'A': 0, 'B': 0, 'C': 0, 'D': 0}
4. 使用“生成式”创建字典
在 Python 中,通过“生成式(comprehensions)”对可迭代对象进行循环处理,可以简单快速的生成一个新的字典。 其语法格式如下:
{ 键_表达式 : 值_表达式 for 表达式 in 可迭代对象 }
d1 = {i: chr(i) for i in range(65, 69)}
print(d1)
------------------------
输出:{65: 'A', 66: 'B', 67: 'C', 68: 'D'}
小结
将以上各种方式进行整理如下:
# 1. 直接赋值
dict1 = {}
# 2. 直接赋值
dict2 = {'name': 'Jonah', 'age': '14'}
# 3. dict() 方式
dict3 = dict()
# 4. dict(**kwargs) 方式
dict4 = dict(name='Jonah', age=14)
# 5. dict(iterable) 方式
lst = [('name', 'Jonah'), ('age', '14')]
dict5 = dict(lst)
# 6. dict(mapping) - zip 方式
zp = zip('ABCD', range(1, 5))
dict6 = dict(zp)
# 7. dict(mapping) - map 方式
mp = map(lambda x, y: (x, y), 'ABCD', range(1, 5))
dict7 = dict(mp)
# 8. dict + kw 方式
d1 = {'name': 'Jonah'}
dict8 = dict(d1, age='14')
# 9. fromkeys 方式
dict9 = dict.fromkeys('ABCD', 0)
# 10. 生成式方式
dict10 = {i: chr(i) for i in range(65, 69)}