10

最近、これを行う方法を見たような気がします。空のdictがあり、その空のdict内のネストされたdictに値を設定したいが、明らかにそのネストされたdictはまだ作成されていないとします。中間キーを作成する1行の方法はありますか?これが私がやりたいことです:

mydict = {}
mydict['foo']['bar']['foobar'] = 25

このコードを実行すると、「foo」のKeyError例外が発生します。中間キーを作成する機能はありますか?

ありがとう。

4

3 に答える 3

19
from collections import defaultdict
recursivedict = lambda: defaultdict(recursivedict)
mydict = recursivedict()

アクセスすると、別のmydict['foo']に設定されます。実際にはforも作成しますが、それをに割り当てると破棄されます。mydict['foo']recursivedictrecursivedictmydict['foo']['bar']['foobar']25

于 2012-04-18T21:45:20.943 に答える
4

別のオプション-用途に応じて、ネストされた辞書の代わりにタプルをキーとして使用することです。

mydict = {}
mydict['foo', 'bar', 'foobar'] = 25

これは、ツリーのブランチをいつでも取得したい場合を除いて、完全に機能します(この場合、mydict ['foo']を取得することはできません)。

ネストのレイヤーがいくつ必要かがわかっている場合はfunctools.partial、ラムダの代わりに使用することもできます。

from functools import partial
from collections import defaultdict

tripledict = partial(defaultdict, partial(defaultdict, dict))
mydict = tripledict()
mydict['foo']['bar']['foobar'] = 25

一部の人々は、同等のラムダベースのソリューションよりも読みやすく、のインスタンスを作成する方が速いと感じています。

python -m timeit -s "from functools import partial" -s "from collections import defaultdict" -s "tripledefaultdict = partial(defaultdict, partial(defaultdict, dict))" "tripledefaultdict()"
1000000 loops, best of 3: 0.281 usec per loop

python -m timeit -s "from collections import defaultdict" -s "recursivedict = lambda: defaultdict(recursivedict)" "recursivedict()"
1000000 loops, best of 3: 0.446 usec per loop

ただし、いつものように、ボトルネックがあることがわかるまで最適化する意味はありません。したがって、最も有用で読みやすいものを選択してから、最速のものを選択してください。

于 2012-04-18T21:57:02.047 に答える
0

なぜしたいかわからないが、:

>>> from collections import defaultdict as dd
>>> mydict = dd(lambda: dd(lambda: {}))
>>> mydict['foo']['bar']['foobar'] = 25
>>> mydict
defaultdict(<function <lambda> at 0x021B8978>, {'foo': defaultdict(<function <lambda> at 0x021B8618>, {'bar': {'foobar': 25}})})
于 2012-04-18T21:48:02.737 に答える