2016-11-29 3 views
1

私は2つのdictsの値としてセットを持っています。2つの既存のdictsからdictを作成

Dct1 = {'a':[1, 2, 3], 'b':[4, 5, 6, 7], 'c':[8, 9, 10], 'd':[11, 12, 13, 14]} 
Dct2 = {'TypeZ':['a', 'b'], 'TypeX':['c', 'd']} 

私は別の辞書を作成したいと考えている:項目の値のキーがDCT2 3の値のアイテムである2かどうかをチェックDCT1 の値の項目を通じて 1.反復します。新しい辞書の設定値としてのdict 1に新しいDCTのためのキーと値の対応する項目としてDCT2のキーを使用しています

Dct3 = {'TypeZ':[1, 2, 3, 4, 5, 6, 7], 'TypeX':[8, 9, 10, 11, 12, 13, 14]} 

私もDCT3の値の重複を避けるためにしたいです。

は、ここで私は現在、(他のdictsが既に正常にビルドされている)に苦しんでいるコードの抜粋です:

RateByType = {} 

for key, item in RoRaDct.items(): 
    for i, j in TpRtDct.items(): 
     for x in item: 
      for y in j: 
       if key == y: 
        RateByType[i].add(item) 

しかし、それは重要なエラーを生成しています。私はdefaultdict(set)を使ってみましたが、TypeError:unhashable型:setを取得しました。後者は、私が最初の2つのdictを構築するために使用した方法です。

+0

あなたは値はセットだと言っていますが、あなたのコードはそれらをリストとして記述しています(重複排除についても議論します)。 'set'型または' list'型の値はありますか? –

+0

Dct2宣言で 'TypeX'の後に' ''がありません – shash678

+0

' Dct3 [' TypeX '] 'に' 11'が含まれているのはなぜですか? –

答えて

1

Dct2のうちのセットを作る年代キー、その後Dct3ためdefaultdictを作成し、Dct2以上のループ年代のキーとそれに対応する値を:

import collections 
Dct1 = {'a':[1,2,3],'b':[4,5,6,7],'c':[8,9,10],'d':[12,12,13,14]} 
Dct2 = {'TypeZ':['a','b'],'TypeX':['c','d']} 
s = set(Dct2) 
d = collections.defaultdict(list) 
for key in Dct2: 
    for k in Dct2[key]: 
     d[key].extend(Dct1[k]) 

結果:

>>> import pprint 
>>> pprint.pprint(d) 
{'TypeX': [8, 9, 10, 12, 12, 13, 14], 
'TypeZ': [1, 2, 3, 4, 5, 6, 7]} 
+0

もう一度ありがとうございます。それは素晴らしい作品です。とにかく、dict 3の値に特定の項目を追加しないようにするにはどうしますか? exclude =( 'c'、 'e')と言って、Dct2 [key]のkのために条件付きの "除外しないならif:after"を挿入しますか? – ShaunO

+0

@ShaunO - それは私のために働く。やってみて。 – TigerhawkT3

0
Dct3 = {k: set.union(*map(lambda x: set(Dct1.get(x, [])), v)) for k, v in Dct2.items()} 

の各キーと値のペアについて、メンバーelemによってマップされたセットの和集合にキーをマップしますDct1のキーである値のents。

EDIT:説明

{k: v for k, v in Dct2.items()} 

Dct2を再現つまり、dictionary comprehensionです。

set.union(*map(lambda x: set(Dct1.get(x, [])), v)) 

私たちはセットを構築するために使用していますが、内側から見ています。

Dct1.get(x, []) 

Dct1[x]にアクセスして返します。辞書がキーxを有していない場合は、空のリストを返す[]

set(Dct1.get(x, [])) 

は上記Dct1.getの結果を取得し、セットに変換します。

lambda x: set(Dct1.get(x, [])) 

は、無名関数を定義する(すなわち、名前を持たない)。その関数は、単に入力xを取り、表現set(Dct1.get(x, []))

map(lambda x: set(Dct1.get(x, [])), v) 

mapを評価するためにそれを使用することは(私たちのラムダ関数、この場合には)別の関数をとる関数と(リストなど)反復可能であるし、次に作りますiterableは、その関数を入力iterableのすべての要素に適用します。

*map(lambda x: set(Dct1.get(x, [])), v) 

*オペレータは、イテラブルを解凍するために使用されます。だから、[1, 2, 3]のように反復可能になりますし、基本的には一緒にすべてを追加し、

set.union(*map(lambda x: set(Dct1.get(x, [])), v)) 

set.unionが労働組合を複数のセットを取り、計算する関数があるadd(*[1, 2, 3])add(1, 2, 3)に変わります。

+0

私はこの答えに感銘を受けましたが、私はそれが私の頭の上にあることを認めなければなりません。それほど正しいとは言いません。ありがとうございました。 – ShaunO

+0

@ShaunOここで何が起こっているのかを説明するために、もっと冗長な書き込みをすることができます。私はここでいくつかの関数型プログラミングツールを使用しています。 –

+0

私はそれの周りに私の頭を包むことができるのが大好きだ。あなたが本当に気にしないなら、私はそれの背後にある論理についてもっと学ぶことに完全になります。 – ShaunO

関連する問題