get 和 setdefault 方法很重要,它们应该在任何 Python 程序员的工具箱中。
另一个重要的方法是使用collections.defaultdict,因为这样你就可以在一个地方定义你的“默认值”,而不必将它分散到你的代码中任何使用字典的地方,即不要重复你自己。然后,如果您更改默认值,则无需通过代码查找所有这些获取和设置默认值。例如
>>> import collections
>>> myDict = collections.defaultdict
>>> myDict = collections.defaultdict(lambda : 1024)
>>> myDict[0] += 1
>>> print myDict[0], myDict[100]
1025 1024
因为你可以设置函数调用,你可以为你的默认值做任何你喜欢的事情。为每个新键分配一个 1 到 10 之间的随机值怎么样?
>>> import collections
>>> import random
>>> myDict = collections.defaultdict(lambda : random.randint(1,10))
>>> print myDict[0], myDict[100]
1 5
>>> print myDict[0], myDict[100], myDict[2]
1 5 6
好的,这个例子有点做作,但我相信你能想到更好的用途。假设您要构建一个昂贵的类 - 仅当密钥实际上不存在时才会创建实例,这与调用 get 和 setdefault 时不同,例如
>>> class ExpensiveClass(object):
>>> numObjects = 0
>>> def __init__(self):
>>> ExpensiveClass.numObjects += 1
>>>
>>> print ExpensiveClass.numObjects
0
>>> x = {}
>>> x[0] = ExpensiveClass()
>>> print ExpensiveClass.numObjects
1
>>> print x.get(0, ExpensiveClass())
<__main__.ExpensiveClass object at 0x025665B0>
>>> print ExpensiveClass.numObjects
2
>>> ExpensiveClass.numObjects = 0
>>> z = collections.defaultdict(ExpensiveClass)
>>> print ExpensiveClass.numObjects
0
>>> print z[0]
>>> <__main__.ExpensiveClass object at 0x02566510>
>>> print ExpensiveClass.numObjects
1
请注意,对x.get 的调用构造了一个新的ExpensiveClass 实例,即使我们从未使用过该实例,因为x[0] 已经存在。如果您确实在尝试计算 ExpensiveClass 对象的数量,或者它们的创建速度非常慢,这可能会导致问题。 collections.defaultdict 不会出现这些问题。