1

私は2つのリストを持っています:

alist =  [11,12,13,11,15]
blist = ['A', 'A', 'B', 'A', 'B']

blistの項目がキーで、alistの項目が値であり、2つのリストのインデックスに対応するリストを持つ辞書を作成したいと思います。

結果は次のようになります。

{'A': [11, 12, 11], 'B': [13, 15]}

私はこれを試しました:

dictNames = {}
for i in xrange(len(alist)):
    for letter in blist:
        if letter not in dictNames:
            dictNames[letter] = []
        else:
            dictNames[letter].append(alist[i])

結果を与える:

{'A': [11, 11, 12, 12, 12, 13, 13, 13, 11, 11, 11, 15, 15, 15], 'B': [11, 12, 12, 13, 13, 11, 11, 15, 15]}

すでに辞書にあるときに追加するのではなく、辞書にある既存の文字に追加しないのはなぜですか?

4

5 に答える 5

6

defaultdict簡単にするために使用します。

from collections import defaultdict

dictNames = defaultdict(list)
for key, value in zip(blist, alist):
    dictNames[key].append(value)

これにより、次のものが作成されます。

>>> dictNames
defaultdict(<type 'list'>, {'A': [11, 12, 11], 'B': [13, 15]})

defaultdictはのサブクラスであるdictため、他のと同じように機能しますdict

なしdefaultdictでは、キーがすでに存在するかどうかをテストする必要がありますsetdefault()

dictNames = {}
for key, value in zip(blist, alist):
    dictNames.setdefault(key, []).append(value)

その結果:

>>> dictNames
{'A': [11, 12, 11], 'B': [13, 15]}

ここでの本当のトリックzip()は、二重ループの代わりにキーリストと値リストを組み合わせるために使用することです。

于 2013-03-21T10:54:58.393 に答える
2

まず、両方のリストをループします。alist内のすべてのアイテムについて、blistをループします。したがって、内側のループは25回実行されます。代わりに、5回実行する必要があるため、ループは1つだけにします。

次に、リストがまだ存在しない場合はリストを正しく初期化しますが、その場合、番号はリストに追加されません。新しいリストであっても、番号は常にリストに追加する必要があります。

これら2つのことを考慮に入れるようにコードを変更しましたが、少しうまく機能します。

for i in xrange(len(alist)):
    letter = blist[i]
    if letter not in dictNames:
        dictNames[letter] = []
    dictNames[letter].append(alist[i])

出力:

{'A': [11, 12, 11], 'B': [13, 15]}
于 2013-03-21T11:00:32.760 に答える
0

この方法は秩序を維持します

from collections import defaultdict

alist =  [11,12,13,11,15]
blist = ['A', 'A', 'B', 'A', 'B']

d = defaultdict(list)
seen = defaultdict(set)

for k, v in zip(blist, alist):
    if v not in seen[k]:
        d[k].append(v)
        seen[k].add(v)

print d

defaultdict(<type 'list'>, {'A': [11, 12], 'B': [13, 15]})
于 2013-03-21T11:03:02.487 に答える
0

これが1行の解決策です。

 {k: [alist[i] for i in range(len(blist)) if blist[i] == k] for k in set(blist)}

唯一の問題は、最悪の場合、時間計算量がO(n ^ 2)であり、大きなリストには不十分であるということです。

于 2013-03-21T11:21:05.513 に答える
0

これは私が現在思いつくことができる最短の表現です:

from itertools import groupby

{k: {x[1] for x in v} for k, v in groupby(sorted(zip(blist, alist)), lambda x: x[0])}

関連する(そしてまだ言及されていない)部分は、への呼び出しgroupbyであり、次の同様の質問でも説明されています:Python group by

于 2013-03-21T11:21:44.187 に答える