web-dev-qa-db-ja.com

defaultdict:最初の引数は呼び出し可能かNoneでなければなりません

私は次のコードを実行しました:

from collections import defaultdict
lst = list(range(0,5))
d = defaultdict(lst)

そして私はこのエラーを受け取りました:

TypeError: first argument must be callable or None

助けてください

12
Arcyno

defaultdictの場合、デフォルト値は通常実際には値ではありません、それはfactory:新しい値を生成するメソッド。この問題を解決するには、リストを生成するlambda式を使用します。

_lst = lambda:list(range(0,5))
d = defaultdict(lst)_

それ以外の場合はすべてのデフォルト値同じリストを参照になるため、これもここでは良いアイデアです。例えばここに:

_d[1].append(14)
_

notは_d[2]_に影響します(_d[1]_と_d[2]_の両方が存在しない場合)。

あなたはしかしこれを達成することができますで:

_val = list(range(0,5))
lst = lambda:val
d = defaultdict(lst)
_

しかし、これは望ましくない副作用をもたらす可能性があります。ここでd[1].append(14)を実行すると、_d[2]_は_[1,2,3,4,5,14]_になり、_d[1] is d[2]_はTrueになります:

_$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from collections import defaultdict
>>> val = list(range(0,5))
>>> lst = lambda:val
>>> d = defaultdict(lst)
>>> d[1]
[0, 1, 2, 3, 4]
>>> d[1].append(14)
>>> d[2]
[0, 1, 2, 3, 4, 14]
>>> d[1] is d[2]
True
_

一方:

_$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from collections import defaultdict
>>> lst = lambda:list(range(0,5))
>>> d = defaultdict(lst)
>>> d[1]
[0, 1, 2, 3, 4]
>>> d[1].append(14)
>>> d[2]
[0, 1, 2, 3, 4]
>>> d[1] is d[2]
False
_
15

たとえば、lambdaを使用して、パラメーターを呼び出し可能にする必要があります。

from collections import defaultdict

d = defaultdict(lambda: list(range(0,5)))
print(d[0])
# [0, 1, 2, 3, 4]
6
Moses Koledoye

デフォルトの辞書 は、最初の引数としてcallableを受け入れます(これは未定義の値のデフォルトのファクトリです)、あなたがしたいことは次のステップ:

from collections import defaultdict


default_factory = (lambda: list(range(0,5))
d = defaultdict(default_factory)

呼び出し可能についての詳細は Pythonの「呼び出し可能」とは何ですか? SO質問を参照してください。

4
Andriy Ivaneyko