Python字典类型数据常见操作及排序
以下均使用bpython
字典的创建
字典的创建主要有2种方法: 直接赋值和根据键赋值。下例中分别使用2种方法创建了字典d1和字典d2。
>>> d1 = {'key3': 4, 'key2': 5, 'key1': 4}
>>> print(d1)
{'key3': 4, 'key2': 5, 'key1': 4, }
>>> d2 = dict()
>>> d2['key5']=1
>>> print(d2)
{'key5': 1}
访问字典的键与值
你可以直接根据dict[‘键名’]获取一个值,也可以通过dict.keys()获取所有的键或者dict.values()获取所有的值。但需要注意的是dict.keys()或dict.values()返回的并非列表,你需要使用list方法才能将所有的键和值转化为列表形式。
>>> d1 = {'key3': 4, 'key2': 5, 'key1': 4}
>>> print(d1['key3'])
4
>>> print(d1.keys())
dict_keys(['key3', 'key2', 'key1'])
>>> print(list(d1.keys()))
['key3', 'key2', 'key1']
>>> print(list(d1.values()))
[4, 5, 4]
注意: 当你尝试用一个不存在的键获取值时会出现KeyError,一个更好的习惯是在获取值前先使用if key in dict来判断一个键是否已经存在。
>>> print(d1['key6'])
Traceback (most recent call last):
File "<input>", line 1, in <module>
KeyError: 'key6'
>>> print('key6' in d1)
False
遍历字典
使用for key, value in dict.items()可以遍历整个字典。如果你只喜欢遍历键名或值,你可以只使用for key in dict.keys()或 for value in dict.values()。
for key, value in d1.items():
print("{}->{}".format(key, value))
for key in d1.keys():
print(key)
for value in d1.values():
print(value)
字典数据的添加
字典与列表一样都是可变类型的数据,所以可以实现数据的添加和修改。实现的方法主要有两种:1是创建新的键名并赋值,2是使用update方法。dict自带的update方法非常有用,不仅可以插入新的键值对,还是实现两个字典合并的首选方法。
>>> print(d1)
{'key3': 4, 'key2': 5, 'key1': 4}
>>> d1.update({'key4':2})
>>> print(d1)
{'key3': 4, 'key2': 5, 'key1': 4, 'key4': 2}
>>> d1['key5']=1
>>> print(d1)
{'key3': 4, 'key2': 5, 'key1': 4, 'key4': 2, 'key5': 1}
注意: 当创建的键名已存在时,dict[‘键名’]只会更新现有值,而不会创建新的键值对。
删除字典元素
利用del dict[‘key’]可以删除一个键值对,利用del dict可以删除整个字典, 使用dict.clear()方法可以清空一个字典。三者还是有很大区别的。
>>> print(d1)
{'key3': 4, 'key2': 5, 'key1': 4, 'key4': 2, 'key5': 1}
>>> del d1['key5']
>>> print(d1)
{'key3': 4, 'key2': 5, 'key1': 4, 'key4': 2}
>>> d1.clear()
>>> print(d1)
{}
>>> del d1
>>> print(d1)
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'd1' is not defined
利用zip方法由两个列表创建字典
zip()函数来可以把2个或多个列表合并,并创建一个元组对的列表,使用dict方法可以将其变成字典。元组对的数量以合并列表的最短长度为准。python 3中zip方法合并列表后生成的是zip对象,必需使用dict方法才能将其变成字典。
>>> l1 = [ 1, 2, 3 ]
>>> l2 = [ 'x', 'y', 'z']
>>> l3 = [ 'x', 'y' ]
>>> zip(l1, l2)
<zip object at 0x031D6828>
>>> print(list(zip(l1, l2)))
[(1, 'x'), (2, 'y'), (3, 'z')]
>>> print(list(zip(l1, l3)))
[(1, 'x'), (2, 'y')]
>>> print(dict(zip(l1,l3)))
{1: 'x', 2: 'y'}
实际上zip方法支持所有可迭代对象(字符串、列表、元祖、字典), 而不仅仅是列表。利用这个特性,我们可以很容易创建各种字典,包括很复杂的字典。我们来看下面2个经典例子。注意zip对象支持直接遍历哦,不需要先转成list或dict哦。
>> > l1 = [1, 2, 3]
>> > str1 = "abc"
>> > print(dict(zip(l1, str1)))
{1: 'a', 2: 'b', 3: 'c'}
>> > name = ["John", "Jim", "Lucy"]
>> > year = [1983, 1985, 1995]
>> > birth_year = dict(zip(name, year))
>> > print(birth_year)
{'John': 1983, 'Jim': 1985, 'Lucy': 1995}
>> > for name, year in zip(name, year):
print("{} - {}".format(name, year))
John - 1983
Jim - 1985
Lucy - 1995
利用zip方法实现键值反转
前文提到zip方法支持所有可迭代对象,也自然支持dict.values()和dict.keys(),利用这个特性我们可以快速实现一个字典的键值反转,如下所示:
>>> d1 = {'key3': 4, 'key2': 5, 'key1': 4, 'key4': 2, }
>>> d2 = dict(zip(d1.values(), d1.keys()))
>>> print(d2)
{4: 'key1', 5: 'key2', 2: 'key4'}
为什么使用zip方法后字典少了一个键? 还记得我们之前提到过键名必需唯一吗? 可见zip方法对字典数据进行反转必需考虑值相同而导致数据丢失的问题。
单个字典根据键名或值排序
使用sorted方法可以对单个字典的键名进行正向或逆向排序(reverse=True),得到是一个排过序的键名列表。然后我们通过使用for key in sorted(d)遍历排过序的键从而得到排过序的值。
>>> d1 = {'key3': 4, 'key2': 5, 'key1': 4, 'key4': 2, }
>>> d3 = sorted(d1)
>>> print(d3)
['key1', 'key2', 'key3', 'key4']
>>> print(sorted(d1, reverse=True))
['key4', 'key3', 'key2', 'key1']
>>> for key in sorted(d1):
print(d1[key])
4
5
4
2
如果我们希望根据值来排序,我们一般有2种方法: 1. 利用zip方法构建键值反转字典再排序。2. 使用匿名函数lambda。方法2通常是一种更好的方法。
方法1: 使用zip方法反转字典
>>> d1 = {'key3': 4, 'key2': 5, 'key1': 4, 'key4': 2, }
>>> d2 = dict(zip(d1.values(), d1.keys()))
>>> print(list(d2.keys()))
[4, 5, 2]
>>> for key in sorted(d2):
print(d2[key])
key4
key1
key2
由于使用zip方法导致了数值的缺失,一个更好的方法是使用lambda函数指定key来排序。
方法2: 使用lambda匿名函数
该方法设置排序的key为d1[k], 即每个键值对的值来排序。
>>> d1 = {'key3': 4, 'key2': 5, 'key1': 4, 'key4': 2, }
>>> d2 = sorted(d1, key=lambda k: d1[k])
>>> print(d2)
['key4', 'key3', 'key1', 'key2']
>>> for key in d2:
print(d1[key])
2
4
4
5