当前位置: 首页 > 科技观察

不是Python字典不能排序,而是你的方法没用!

时间:2023-03-12 02:38:44 科技观察

dictionary是Python语言中的一种数据结构,每个字典元素由一对key-value组成。字典的键和值以集合(Set)的形式组织起来,便于快速查询。集合的存储形状通常是树状结构,所以查找速度非常快。我们可以单独通过字典的keys方法和values方法获取键集和值集的可迭代对象,代码如下:x={'x':20,'a':12,'b':5}print(x.keys())print(x.values())执行这段代码,会输出如下内容:dict_keys(['x','a','b'])dict_values([20,12,5])PS:dict_keys和dict_values是Python的两个内部类,它们都是用树结构来组织数据的。现在的问题是集合是无序的(因为它是以树形结构存储的),但是由于某些需求,我们希望得到有序的键值,这就导致了下面的问题:Q1:集合可以排序吗?Q2:排序后能得到键值对吗?Q3:除了键值排序,是否可以按值排序?为了回答这些问题,请继续阅读以下内容。1、藏品可以分类吗?这个问题的答案是:不能。既然叫集合,由于数据的存储形式,必然是无序的,但是我们可以做一个折衷。既然集合不能排序,那么可以将集合中的数据排序,放入一个可以排序的数据结构(比如列表)中,就可以在一定程度上解决我们的问题。看下面的代码:x={'x':20,'a':12,'b':5}keys=sorted(x.keys())values=sorted(x.values())print(type(keys))print(type(values))print(keys)print(values)这段代码中使用了sorted函数,可以用来对序列进行排序,并将排序后的结果放入一个列表中,最后返回thislist,所以执行这段代码会输出如下:['a','b','x'][5,12,20]现在我们第一个问题就解决了,使用sorted函数将集合按升序排列,并以列表的形式显示。如果想降序排序,需要设置reverse参数为True,代码如下:keys=sorted(x.keys(),reverse=True)values=sorted(x.values(),reverse=True)2.排序后,能否得到成对的key-value?现在我们来解决第二个问题。这篇文章讨论的是字典,所以连键和值的排序都不是我们所期望的。我们期望的是得到字典中的键值对,以及已经排序好的键值对。这个问题也很容易解决。既然已经得到了排序好的key,那么就用key从字典中获取对应的value,这样就可以组成一对key-value了。代码如下:x={'x':20,'a':12,'b':5}keys=sorted(x.keys())forkeyinkeys:print(f"{key}:{x[key]}")执行这段代码,输出结果如下Thecontent:x:20b:5a:12显然,输出的键值对是按照key的升序排列的。3、除了键值排序,是否可以按值排序?按值排序没问题,但是排序后的值就没用了。因为字典无法通过值反向获取键。所以通过前面的方法只能得到排序后的值。所以需要作为sorted函数的key参数,用来指定是使用key还是value进行排序。如果您使用的是Python3.7或更高版本。可以为key参数值指定lambda表达式,代码如下:y1={k:vfork,vinsorted(x.items(),key=lambdaitem:item[1])}print(y1)#Sortbyvalueindescendingordery2={k:vfork,vinsorted(x.items(),key=lambdaitem:item[1],reverse=True)}print(y2)这段代码使用for-in表达式生成字典,其中x是要排序的字典。items获取键值对。lambda表达式的项是当前键值对。item[0]表示键,item[1]表示值,所以使用item[1]表示按值排序,使用item[0]表示按键排序。执行此代码将输出以下结果:{'b':5,'a':12,'x':20}{'x':20,'a':12,'b':5}if如果你不想用for-in表达式,也可以用dict函数。代码如下:print(dict(sorted(x.items(),key=lambdaitem:item[1])))如果你不想使用lambda表达式,或者需要更复杂的排序规则,你可以自定义排序规则功能。代码如下:defdict_val(x):returnx[1]sorted_x=sorted(x.items(),key=dict_val)如果读者使用Python3.6或以下版本,可以使用如下代码:importoperator#byvaluesorted_x=sorted(x.items(),key=operator.itemgetter(1))print(type(sorted_x))#listprint(sorted_x)#so用列表替换importoperator#bykeysorted_x=sorted(x.items(),key=operator.itemgetter(0))print(sorted_x)在这段代码中,将返回一个排序列表。列表的元素是元组的形式,第一个值是键。第二个价值是价值。当然,您可以将这些数据重新插入到新字典中。执行此代码将输出以下内容:[('b',5),('a',12),('x',20)][('a',12),('b',5),('x',20)]如果还想通过key在字典中查找值,可以使用OrderedDict对象将sorted_x转换为有序字典。代码如下:importcollectionssorted_dict=collections.OrderedDict(sorted_x)print(type(sorted_dict))print(sorted_dict)print(sorted_dict.get('b'))执行这段代码会输出如下:OrderedDict([('a',12),('b',5),('x',20)])5总结:本文的核心是sorted函数。通过这个功能,可以对键值集合进行排序,也可以对键值对进行排序。如果是后者,则需要指定是使用key还是value进行key排序。sorted函数返回一个排序列表。如果想得到排序后的字典,既可以使用for-in表达式处理,也可以使用dict函数进行转换。当然,如果只是想通过key查找值,也可以将数据放在OrderedDict对象中。本文转载自微信公众号“极客起源”,可通过以下二维码关注。转载本文请联系极客本源公众号。