defaultdict constant_factory的行为不符合预期 [英] defaultdict constant_factory doesn't behave as expected

查看:105
本文介绍了defaultdict constant_factory的行为不符合预期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我愿意将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆