python字典的常见操作_一文看懂Python字典类型数据常见操作及排序

Python的字典(dictionary)是一种灵活的数据结构类型,字典的每个键值对(key=>value)用冒号(:)分割,每个对之间用逗号(,)分割。Python字典里的键必须独一无二,但值则不必的。字典的值可以取任何数据类型,但必须是不可变的(unhashable),如字符串,元组或数值, 用列表是不行的。本文教你一文看懂Python字典类型数据常见操作和排序。

字典的创建

字典的创建主要有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 "", line 1, in

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 "", line 1, in

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)

>>> 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

字典的运算

假设我们有如下两个字典,我们能实现直接相加或相减吗? 答案是不能。Python 3并不支持字典的直接相加或相减。如果你要合并两个字典,需要使用dict.update()方法。

>>> d1 = {'key1':1, 'key2':7}

>>> d2 = {'key1':3, 'key3':4}

虽然python不支持加减运算,但支持针对keys()和values()类似集合的运算, 可以用来求同求异,代码如下所示:

>>> d1.keys() & d2.keys()

{'key1'}

>>> d1.keys() - d2.keys()

{'key2'}

你有没有发现字典的默认运算一般是针对键进行的?

提取字典子集

假设我们有如下一个字典(姓名->分数),我们需要提取分数大于60的键值对组成一个新的字典子集,我们应该怎么办呢?

d = {'John':50, 'Mary': 65, 'Kitty':90, 'Tom': 100}

最好最快的方式就是使用字典推倒表达式,方法如下。该方法工作常用,考试必考,请一定要熟练掌握哦。

>>> d = {'John':50, 'Mary': 65, 'Kitty':90, 'Tom': 100}

>>> sub_d = { key:value for key, value in d.items() if value >= 60 }

>>> print(sub_d)

{'Mary': 65, 'Kitty': 90, 'Tom': 100}

字典列表的排序

实际应用中更常见的是对字典列表排序,而不是对当个字典的键或值进行排序。假设你有一个字典列表,你想根据某个或某几个字典字段来排序这个列表。这时你需要使用 operator 模块的 itemgetter 函数,可以非常容易的排序这样的数据结构。 假设你从数据库中检索出来网站会员信息列表,并且以下列的数据结构返回:

rows = [

{'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},

{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},

{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},

{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}]

根据任意的字典字段来排序输入结果行是很容易实现的,代码示例:

from operator import itemgetter

rows_by_fname = sorted(rows, key=itemgetter('fname'))

print(rows_by_fname)

代码的输出如下。注意该方法返回的直接排过序的完整字典,而不是排过序的键名列表。

[{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'},

{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'},

{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},

{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'}]

itemgetter() 函数也支持多个 keys,比如下面的代码

rows_by_lfname = sorted(rows, key=itemgetter('lname','fname'))

print(rows_by_lfname)

输出如下:

[{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},

{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'},

{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'},

{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'}]

本节关于字典列表的排序介绍来自python cookbook。

字典列表的去重

假设我们有如下一个字典列表,我们需要实现字典值的去重,即提取所有独特的值组成一个列表。一个最好的方式就是使用列表表达式。

>>> d1 = [{'key1':2}, {'key1':3}, {'key2': 2}, {'key3':4}]

>>> u_value = set(val for dict in d1 for val in dict.values())

>>> print(list(u_value))

[2, 3, 4]

同样的你可以使用列表表达式提取所有独特的键名组成一个列表。

>>> d1 = [{'key1':2}, {'key1':3}, {'key2': 2}, {'key3':4}]

>>> u_key = set(key for dict in d1 for key in dict.keys())

>>> print(list(u_key))

['key2', 'key3', 'key1']

小结

本文总结了Python字典类型数据常见操作(如创建,添加,修改和删除), 还重点讲解了字典和字典列表的排序和去重。如果喜欢本文就点赞吧。如果对Python基础感兴趣,也欢迎阅读我们的一文看懂Python系列原创文章。

大江狗

2018.11.6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值