2

それは簡単な作業のようです:

値を上書きせずに 2 つの辞書をマージしようとしていますが、追加しています。

a = {1: [(1,1)],2: [(2,2),(3,3)],3: [(4,4)]} 
b = {3: [(5,5)], 4: [(6,6)]}

タプル数 a = 4、タプル数 b = 2

これが、これらのオプションが上書きされているため、これらのオプションを除外した理由です。

all = dict(a.items() + b.items()) 
all = dict(a, **b)
all = a.update([b])

次の解決策は問題なく機能しますが、元の辞書 a にも値を追加します。

all = {}

for k in a.keys():
    if k in all:
        all[k].append(a[k])
    else:
        all[k] = a[k]


for k in b.keys():
    if k in all:
        all[k].append(b[k])
    else:
        all[k] = b[k]

出力 =

a = {1: [(1, 1)], 2: [(2, 2), (3, 3)], 3: [(4, 4), **[(5, 5)]**]}
b = {3: [(5, 5)], 4: [(6, 6)]}
c = {1: [(1, 1)], 2: [(2, 2), (3, 3)], 3: [(4, 4), [(5, 5)]], 4: [(6, 6)]}

タプル数 a = 5!!!!! 、タプル数 b = 2 (正解)、タプル数 all = 6 (正解)

[(5,5)]b から a にタプルを追加しました。私がコーディングしているのはすべてを完全な辞書「all」に書き込むことだけなので、なぜこれが起こるのかわかりません。

誰でも dict(a) を変更している場所を教えてもらえますか???????

どんな助けでも大歓迎です。

4

3 に答える 3

6

リストをマージする.extend代わりに使用します。.append

>>> example = [1, 2, 3]
>>> example.append([4, 5])
>>> example
[1, 2, 3, [4, 5]]
>>> example.extend([6, 7])
>>> example
[1, 2, 3, [4, 5], 6, 7]

さらに、次を使用して、aとの両方のキーと値をループすることができます。bitertools.chain

from itertools import chain
all = {}
for k, v in chain(a.iteritems(), b.iteritems()):
    all.setdefault(k, []).extend(v)

.setdefault()キーを検索し、まだ存在しない場合はデフォルトに設定します。collections.defaultdictまたは、同じことを暗黙的に行うために使用することもできます。

出力:

>>> a
{1: [(1, 1)], 2: [(2, 2), (3, 3)], 3: [(4, 4)]}
>>> b
{3: [(5,5)], 4: [(6,6)]}
>>> all
{1: [(1, 1)], 2: [(2, 2), (3, 3)], 3: [(4, 4), (5, 5)], 4: [(6, 6)]}

最初に各キーのクリーンな新しいリストを作成してから拡張するため、元のリストaは影響を受けないことに注意してください。あなたのコードでは、リストのコピーを作成しません。代わりに、リストへの参照をコピーしました。最終的に、alladict の両方の値が同じリストを指し、これらのリストに追加を使用すると、両方の場所で変更が表示されます。

辞書の代わりに単純な変数を使用すると、簡単に実証できます。

>>> foo = [1, 2, 3]
>>> bar = foo
>>> bar
[1, 2, 3]
>>> bar.append(4)
>>> foo, bar
([1, 2, 3, 4], [1, 2, 3, 4])
>>> id(foo), id(bar)
(4477098392, 4477098392)

両方とも同じリストを参照していますが、リストはコピーされませんでしたfoobar代わりにコピーを作成するには、list()コンストラクターを使用するか、[:]スライス演算子を使用します。

>>> bar = foo[:]
>>> bar.append(5)
>>> foo, bar
([1, 2, 3, 4], [1, 2, 3, 4, 5])
>>> id(foo), id(bar)
(4477098392, 4477098536)

barはリストの新しいコピーになり、変更は に表示されなくなりましたfoo。メモリ アドレス (id()呼び出しの結果) は、2 つのリストで異なります。

于 2012-08-25T11:05:48.343 に答える
4

組み合わせたものである3番目の辞書が必要な場合は、collection.defaultdict

from collections import defaultdict
from itertools import chain
all = defaultdict(list)
for k,v in chain(a.iteritems(), b.iteritems()):
    all[k].extend(v)

出力

defaultdict(<type 'list'>, {1: [(1, 1)], 2: [(2, 2), (3, 3)], 3: [(4, 4), (5, 5)], 4: [(6, 6)]})
于 2012-08-25T11:08:46.760 に答える
1

変更の理由の説明として、aループを検討してください。

for k in a.keys():
    if k in all:
        all[k].append(a[k])
    else:
        all[k] = a[k]

kそのため、まだ にない場合は、パーツallを入力して、リストを指します。これはコピーではなく、 への参照です。これらは基本的に同じオブジェクトです。次の反復では、が定義され、それに追加します: しかし、 を指しているので、 にも追加することになります。elseall[k] a[k]a[k]all[k]all[k]a[k]a[k]

を避けたいall[k] = a[k]。あなたはそれを試すことができます:

for k in a.keys():
    if k not in all:
        all[k] = []
    all[k].extend(a[k])

( @Martijn Pieters が指摘したように、 のextend代わりに に注意してください)。appendここでは、 をall[k]指すことはないa[k]ので安全です。ただし、@Martijn Pietersの答えははるかに簡潔でエレガントなので、それを使用する必要があります。

于 2012-08-25T12:57:56.123 に答える