我愿意将defaultdict
与 ad hoc default_factory
一起使用,这更符合我的目的。 default_factory
为[0,0]
。
我已经实现了constant_factory
功能:
def constant_factory(value):
return itertools.repeat(value).next
然后当我尝试使用它时,我的defaultdict
有一个意想不到的行为(至少是我没想到的行为)。
以下是一个例子:
>>>import itertools
>>>from collections import defaultdict
>>>dictio=defaultdict(constant_factory([0,0]))
>>>for i in xrange(10):
... dictio[i][0]+=1
>>>dictio
defaultdict(<method-wrapper 'next' of itertools.repeat object at 0x000000000355FC50>, {0: [10, 0], 1: [10, 0], 2: [10, 0], 3: [10, 0], 4: [10, 0], 5: [10, 0], 6: [10, 0], 7: [10, 0], 8: [10, 0], 9: [10, 0]})
相反,我想得到:defaultdict(<method-wrapper 'next' of itertools.repeat object at 0x000000000355FC50>, {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0], 4: [1, 0], 5: [1, 0], 6: [1, 0], 7: [1, 0], 8: [1, 0], 9: [1, 0]})
似乎每次我愿意增加与键i
对应的列表的第一个插槽的值时,它会增加第一个插槽的所有值。
由于我很擅长使用defaultdict和方法包装器,任何人都可以解释一下我做错了什么,因为我相信Python的工作做得非常好吗?
答案 0 :(得分:4)
首先,只需使用:
defaultdict(lambda: [0, 0])
你相当精细的可调用性一遍又一遍地返回相同的列表。您在字典中使用所有值的相同列表。上面的lambda每次调用时都会返回一个 new 列表:
>>> import itertools
>>> lambda_default = lambda: [0, 0]
>>> iter_default = itertools.repeat([0, 0]).next
>>> lambda_default() is lambda_default()
False
>>> iter_default() is iter_default()
True
因此,您可以使用对一个列表的引用来填充您的字典,并且在一个列表中的值更改将反映在打印该列表的引用的任何位置。