2017-03-18 9 views
0

idに2つのdictをマージしたい。 Dict xには、idごとに異なるIDと行数が多数含まれています。 Dict yには複数のキー値が含まれており、常にdict xより少ない行しか持たない。私が欲しいキー値でグルーピングされたdictsのリストをPythonでマージする

x = [{'costgroup': '1', 'POC1': '2', 'post': '5','id': '1'}, 
    {'costgroup': '2', 'POC1': '1', 'post': '4','id': '1'}, 
    {'costgroup': '3', 'POC1': '5', 'post': '2', 'id': '1'}, 
    {'costgroup': '1', 'POC1': '2', 'post': '5','id': '2'}, 
    {'costgroup': '2', 'POC1': '1', 'post': '4','id': '2'}, 
    {'costgroup': '3', 'POC1': '5', 'post': '2', 'id': '2'}, 
    {'costgroup': '3', 'POC1': '5', 'post': '2', 'id': '2'}] 


y = [{'id': '1', 'laminate': 'D'}, 
    { 'id':'2', 'laminate': T'}]  

出力は以下の通りです:

z = [{'costgroup': '1', 'POC1': '2', 'post': '5','id': '1','laminate':'D'}, 
    {'costgroup': '2', 'POC1': '1', 'post': '4','id': '1','laminate': 'D'}, 
    {'costgroup': '3', 'POC1': '5', 'post': '2', 'id': '1','laminate': 'D'}, 
    {'costgroup': '1', 'POC1': '2', 'post': '5','id': '2','laminate': 'T'}, 
    {'costgroup': '2', 'POC1': '1', 'post': '4','id': '2','laminate': 'T'}, 
    {'costgroup': '3', 'POC1': '5', 'post': '2', 'id': '2','laminate': 'T'}, 
    {'costgroup': '3', 'POC1': '5', 'post': '2', 'id': '2','laminate': 'T'}] 

これはパンダ

dfx = pd.DataFrame(x) 
dfy = pd.DataFrame(y) 
pd.merge(dfx,dfy, how ='left', left_on = 'id', right_on = 'id') 

を使用して達成するのは簡単です。しかし、私はAWSラムダ関数を使用して、この適用するつもりです私はパンダのオーバーヘッドを望んでおらず、アウトプットはディクテーションである必要があります。下のコードを試してみましたが、私はIDの別の値を見つけて反復するために何かを追加しなければなりませんでした。しかし、まだ必要な出力はありません。

valuelist = ['1'] 
def copyf(dictlist, key, valuelist): 
     return [d for d in dictlist if d[key] in valuelist] 

y1 = copyf(y, 'id', valuelist) 
x1 = copyf(x, 'id', valuelist) 
y1.append(x1) 

上記の内容は興味深いものですが、私が必要とするものではありません。

[{'distance': '2', 'id': '1', 'laminate': 'D'}, 
[{'POC1': '2', 'costgroup': '1', 'id': '1', 'post': '5'}, 
    {'POC1': '1', 'costgroup': '2', 'id': '1', 'post': '4'}, 
    {'POC1': '5', 'costgroup': '3', 'id': '1', 'post': '2'}]] 
+0

'ids'は' y'で一意ですか? – schwobaseggl

+0

はいidsはyで一意です – Erich

答えて

2
def merge(d1, d2): 
    """Given two dicts, merge them into a new dict as a shallow copy.""" 
    result = d1.copy() 
    result.update(d2) 
    return result 

result = [merge(d1, d2) for d1 in x for d2 in y if d1["id"] == d2["id"]] 
print(result) 

生成し、ここから

[{'POC1': '2', 'costgroup': '1', 'id': '1', 'laminate': 'D', 'post': '5'}, 
{'POC1': '1', 'costgroup': '2', 'id': '1', 'laminate': 'D', 'post': '4'}, 
{'POC1': '5', 'costgroup': '3', 'id': '1', 'laminate': 'D', 'post': '2'}, 
{'POC1': '2', 'costgroup': '1', 'id': '2', 'laminate': 'T', 'post': '5'}, 
{'POC1': '1', 'costgroup': '2', 'id': '2', 'laminate': 'T', 'post': '4'}, 
{'POC1': '5', 'costgroup': '3', 'id': '2', 'laminate': 'T', 'post': '2'}, 
{'POC1': '5', 'costgroup': '3', 'id': '2', 'laminate': 'T', 'post': '2'}] 

マージ機能与える:How to merge two Python dictionaries in a single expression?

Python 3.5ではより簡潔な構文がありますが、2.7になっています。

2
import copy 

x = [{'costgroup': '1', 'POC1': '2', 'post': '5','id': '1'}, 
    {'costgroup': '2', 'POC1': '1', 'post': '4','id': '1'}, 
    {'costgroup': '3', 'POC1': '5', 'post': '2', 'id': '1'}, 
    {'costgroup': '1', 'POC1': '2', 'post': '5','id': '2'}, 
    {'costgroup': '2', 'POC1': '1', 'post': '4','id': '2'}, 
    {'costgroup': '3', 'POC1': '5', 'post': '2', 'id': '2'}, 
    {'costgroup': '3', 'POC1': '5', 'post': '2', 'id': '2'}] 


y = [{'id': '1', 'laminate': 'D'}, 
    { 'id':'2', 'laminate': 'T'} 
] 

#create the id->laminate mapping 
m = { d['id']: d['laminate'] for d in y } 

#create the final output 
z = [] 
for d in x: 
    #make a copy of the dictionary from x so that the input data 
    #is not overwritten 
    item = dict(d) #copy.deepcopy(d) 
    item.update({'laminate': m[d['id']]}) 
    z.append(item) 

print(z) 

これは

[ 
{'laminate': 'D', 'post': '5', 'POC1': '2', 'id': '1', 'costgroup': '1'}, 
{'laminate': 'D', 'post': '4', 'POC1': '1', 'id': '1', 'costgroup': '2'}, 
{'laminate': 'D', 'post': '2', 'POC1': '5', 'id': '1', 'costgroup': '3'}, 
{'laminate': 'T', 'post': '5', 'POC1': '2', 'id': '2', 'costgroup': '1'}, 
{'laminate': 'T', 'post': '4', 'POC1': '1', 'id': '2', 'costgroup': '2'}, 
{'laminate': 'T', 'post': '2', 'POC1': '5', 'id': '2', 'costgroup': '3'}, 
{'laminate': 'T', 'post': '2', 'POC1': '5', 'id': '2', 'costgroup': '3'}] 
1
z = [] 
for dx in x: 
    for dy in y: 
     if dx['id'] == dy['id']: 
      z.append(dict(dx.items() + dy.items())) 

print z 
関連する問題