1

我愿意使用更适合我的目的defaultdictad hoc 。 default_factorydefault_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]})

看来,每次我愿意增加与 key 对应的列表的第一个槽的i值时,它都会增加第一个槽的所有值。

由于我对使用 defaultdict 和方法包装器很陌生,任何人都可以解释我做错了什么,因为我相信 Python 做得很好吗?

4

1 回答 1

4

首先,只需使用:

defaultdict(lambda: [0, 0])

您相当精细的可调用对象一遍又一遍地返回相同的列表。您对字典中的所有值使用相同的列表。上面的 lambda每次被调用时都会返回一个新列表:

>>> 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

因此,您使用对一个列表的引用填充您的字典,并且更改该列表中的值会反映在打印对该列表的引用的任何地方。

于 2013-08-07T16:32:58.190 回答