1

私は、自分の目的により適したアドホックdefaultdictで喜んで使用します。でしょう。 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])

かなり精巧な callable が同じリストを何度も返します。辞書内のすべての値に同じリストを使用しています。上記のラムダは、代わりに呼び出されるたびに新しいリストを返します。

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

したがって、 1 つのリストへの参照を辞書に入力すると、その 1 つのリストの値を変更すると、その 1 つのリストへの参照が出力されるすべての場所に反映されます。

于 2013-08-07T16:32:58.190 に答える