Contents
30.2.5. 字典很多时候是无序的¶
从Python3.6开始,字典会保留键值对在添加时所用的顺序。
In [7]: baby_names = { 'cat': 'kitten', 'dog': 'puppy',}
In [8]: print(baby_names)
{'cat': 'kitten', 'dog': 'puppy'}
In [9]: print(baby_names)
{'cat': 'kitten', 'dog': 'puppy'}
在Python3.5之前的版本中,dict所提供的许多方法都不保证固定的顺序,所以让人觉得好像是随机处理的。
在新版的Python中,这些方法可以按照当初添加键值对的顺序来处理了。
这项变化对Python中那些依赖字典类型及其实现细节的特性产生了很多影响。 函数的关键字参数,以前是按照近乎随机的顺序出现,现在,这些关键字参数总能保留调用函数时所指定的那套顺序。
In [1]: def my_func(**kwargs):
...: for key, value in kwargs.items():
...: print(f'{key} = {value}')
...:
...: my_func(goose='gosling', kangaroo='joey')
...:
...:
goose = gosling
kangaroo = joey
另外,类也会利用字典来保存这个类的实例所具备的一些数据。
In [1]: class MyClass:
...: def __init__(self):
...: self.alligator = "hatchling"
...: self.elephant = "calf"
...: a = MyClass()
...: for key,value in a.__dict__.items():
...: print(f"{key} = {value}")
...:
alligator = hatchling
elephant = calf
Python不是静态类型的语音,大多数代码都以鸭子类型机制运作(即对象支持什么样的行为,就可以当成什么样的数据使用,而不用执着于它在类体系中的地位)。这种特性可能会产生意想不到的问题。
统计各种小动物的受欢迎程度。我们可以设定一个字典,把每种动物和它得到的票数关联起来。
In [2]: votes = {
...: 'otter': 1281,
...: 'polar bear': 587,
...: 'fox': 863,
...: }
In [3]:
#现在定义一个函数来处理投票数据。用户可以把空的字典传给这个函数,这样的话,它就会把每个动物及其排名放到这个字典中。
In [3]: def populate_ranks(votes, ranks):
...: names = list(votes.keys())
...: names.sort(key=votes.get, reverse=True)
...: for i, name in enumerate(names, 1):
...: ranks[name] = i
...:
#我们还需要写一个函数查出人气最高的动物。这个函数假定populate_ranks总是会按照升序向字典写入键值对,这样第一个出现在字典里的就应该是排名最靠前的动物。
In [4]: def get_winner(ranks):
...: return next(iter(ranks))
...:
...:
In [5]: ranks = {}
...: populate_ranks(votes, ranks)
...: print(ranks)
...: winner = get_winner(ranks)
...: print(winner)
...:
...:
{'otter': 1, 'fox': 2, 'polar bear': 3}
otter
假设现在需求变了,我们想要按照字母顺序在UI中显示。为了实现这种效果,我们用内置的collections.abc模块定义这样一个类。这个类的功能和字典一样,而且会按照字母顺序迭代其中的内容。