9

アルゴリズムを探していましたが、dictdに値が含まれている理由と含まれていない理由がわかりcurrません。口述するために何もされていないようだと思いますd

>>> def what(*words):
...     d = {}
...     print d
...     for word in words:
...     print 'word: ' + word
...         curr = d
...         for letter in word:
...             curr = curr.setdefault(letter, {})
...         curr = curr.setdefault('.', '.')
...     print d
...     print '?'
...     print curr
...     return 1
... 
>>> what('foo') 
{}
word: foo
{'f': {'o': {'o': {'.': '.'}}}}
?
.
1
4

3 に答える 3

13

のドキュメントを読んでくださいdict.setdefault: のようですgetが、キーが存在しない場合は、それも設定されます:

>>> my_dict = {}
>>> my_dict.setdefault('some key', 'a value')
'a value'
>>> my_dict
{'some key': 'a value'}
>>> my_dict.get('some key2', 'a value2')
'a value2'
>>> my_dict
{'some key': 'a value'}

例を少し変更します。

>>> def what(*words):
...     d = dict()
...     for word in words:
...             curr = d
...             for letter in word:
...                     curr = curr.setdefault(letter, {})
...             curr = curr.setdefault('.', '.')
...             print 'curr is now: %r while d is %r' % (curr, d)
... 
>>> what('foo')
curr is now: '.' while d is {'f': {'o': {'o': {'.': '.'}}}}

変更を見ることができるように、時々(あなたの例では常に)curr呼び出すときに新しいを作成し、常に元のを参照しながら、新しいを作成して値として設定するためです。ご覧のとおり、値は とかなり異なるため、ループの後に変更されます。setdefaultdictcurrddict{'f': {'o': {'o': {'.': '.'}}}}{}

おそらくあなたの混乱は、curr = curr.setdefault(letter, {}) 常に新しい のを作成しdict、それが割り当てられるという事実によるものですcurr(したがって、すべての文字に対してdict、値を上書きするのではなく、オリジナルにネスト レベルを追加します)。

これを参照してください:

>>> my_dict = {}
>>> curr = my_dict
>>> for letter in 'foo':
...     print 'my_dict is now %r. curr is now %r' % (my_dict, curr)
...     curr = curr.setdefault(letter, {})
... 
my_dict is now {}. curr is now {}
my_dict is now {'f': {}}. curr is now {}
my_dict is now {'f': {'o': {}}}. curr is now {}
>>> my_dict
{'f': {'o': {'o': {}}}}

すべてのレベルでわかるようにmy_dict、新しいネスト レベルがあります。

たぶん、しかし私は推測していますが、あなたは のようなものを取得したかったの'foo' -> {'f': {}, 'o': {}}です。

>>> my_dict = {}
>>> for letter in 'foo':
...     my_dict.setdefault(letter, {})
... 
>>> my_dict
{'o': {}, 'f': {}}
于 2013-03-21T18:49:08.203 に答える
4

d = dict()--> 空の辞書を初期化し、名前にバインドしdます。{}つまり、名前で参照される辞書オブジェクト ( ) があります。d

外側の for ループ内--> 別の名前を同じオブジェクトに
curr = dバインドします。currしたがって、名前 (dcurrは同じオブジェクトを参照します)

内側の for ループの内側
最初の反復中letter = 'f'

curr = curr.setdefault(letter, {})

上記のステートメントで起こっていることが 2 つあります。

A) curr.setdefault(letter, {})--> ドキュメントによると:

「キーが辞書にある場合は、その値を返します。そうでない場合は、デフォルトの値でキーを挿入し、デフォルトを返します。デフォルトのデフォルトはなしです。」.

文字「f」は最初の辞書オブジェクトにないため、最初のオブジェクトを変更し{'f':{}}て値を返します{}。これは最初の辞書オブジェクトではなく、setdefault ステートメントのために作成された新しいオブジェクトです。この時点で、 と の両方currが にd変更された最初の辞書オブジェクトを参照します{'f':{}}

B)curr上記の戻り値への名前の再割り当て。ここで、名前currdは異なるオブジェクトを参照します。dはオブジェクト{'f':{}}curr参照し、実際には の値である空の辞書オブジェクトを参照しますd['f']。これが、ループを通過するときに、元のディクショナリ オブジェクトでネストが発生する理由です。

于 2014-08-12T11:38:28.823 に答える