dict.fromkeys と可変オブジェクトの謎を明らかにする
Python の dict.fromkeys 関数は、可変オブジェクトで使用すると予期しない動作をする可能性があります。次の例で示すように:
<code class="python">xs = dict.fromkeys(range(2), []) xs[0].append(1) # xs now contains {0: [1], 1: [1]} instead of {0: [1], 1: []}</code>
不可解な動作
この動作は、キーごとに個別の値を保持する辞書内包表記の動作と一見矛盾しています。
<code class="python">xs = {i: [] for i in range(2)} xs[0].append(1) # xs still contains {0: [1], 1: []}</code>
矛盾を理解する
主な違いは、これら 2 つのメソッドが辞書を作成する方法にあります。 Python 2.6 (およびそれ以前) では、dict.fromkeys はすべてのキーに対して同じ変更可能なオブジェクトを参照しますが、辞書内包表記ではキーごとに個別のオブジェクトが作成されます。
結果は、xs[0] が最初のキーで変更されると次のようになります。たとえば、xs[1] は同じリスト オブジェクトを参照しているため、変更は xs[1] に反映されます。対照的に、2 番目の例では、リストは個別であるため、xs[0] を変更しても xs[1] には影響しません。
サプライズの回避
回避するにはこの予期しない動作が発生する可能性があるため、可能な限り辞書内包表記を使用することをお勧めします。辞書内包表記が利用できない場合 (Python 2.6 など)、dict 関数を使用したジェネレータ式を使用して個別のオブジェクトを作成することも代替手段です:
<code class="python">xs = dict((i, []) for i in range(2))</code>
以上が以下に、「謎」と「予期せぬ動作」の側面を考慮したタイトルのオプションをいくつか示します。 * なぜ `dict.fromkeys` は可変オブジェクトに対して非常に奇妙な動作をするのでしょうか? * `dの謎の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。