defaultdict constant_factory的行为不符合预期 [英] defaultdict constant_factory doesn't behave as expected
问题描述
我愿意将defaultdict
与 ad default_factory
一起使用,这更适合我的目的. default_factory
应该是[0,0]
.
I'm willing to use defaultdict
with an ad hoc default_factory
which suits better my purpose. The default_factory
would be [0,0]
.
我已经实现了constant_factory
函数:
def constant_factory(value):
return itertools.repeat(value).next
然后,当我尝试使用它时,我的defaultdict
出现了意外的行为(至少是我没有想到的行为).
Then when I try to use it, my defaultdict
has an unexpected behavior (at least a behavior I didn't expect).
这里是一个例子:
>>>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
对应的列表的第一个槽的值时,它都会增加第一个槽的所有值.
It seems that, each time I'm willing to increment the value of the first slot of the list corresponding to the key i
, it increments all the values of the the first slots.
由于我刚开始使用defaultdict和方法包装器,因此有人可以向我解释我在做错什么,因为我相信Python可以很好地完成其工作?
Since I'm pretty new to using defaultdict and method wrapper can anybody explain me what I am doing wrong since I believe Python is doing its work perfectly well ?
推荐答案
首先,只需使用:
defaultdict(lambda: [0, 0])
一遍又一遍地细化您的可调用收益相同列表.您正在为词典中的所有值使用相同的列表.每次调用时,上述lambda都会返回一个 new 列表:
Your rather elaborate callable returns the same list over and over again. You are using the same list for all values in your dictionary. The above lambda returns a new list each time it is called instead:
>>> 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
因此,您在词典中填充了对一个列表的引用,并且在打印该一个列表的引用的任何地方都反映了更改该列表中的值.
You thus fill your dictionary with references to one list, and altering values in that one list is reflected everywhere the reference to that one list is printed.
这篇关于defaultdict constant_factory的行为不符合预期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!