1

I have 2 lists of dictionaries, say:

l1 = [{"customer":"amy", "order":2}, {"customer":"amy", "order":3}, {"customer":"basil", "order":4}]
l2 = [{"customer":"amy", "died":"who fell down the stairs"}, {"customer":'basil', "died":"assaulted by bears"}]

I am looking for an elegant way of taking the keys from l2 and putting them into l1. This is for joining lists of dictionaries that use different values as their index

The function should look something like join(l1,l2,'customer'), and produce

l3 = [{"customer":"amy", "order":2,"died":"who fell down the stairs"}, {"customer":"amy", "order":3,"died":"who fell down the stairs"}, {"customer":"basil", "order":4,"died":"assaulted by bears"}}]

l3 should have a dictionary for every dictionary in l1.

if l1 and l2 have the same non-joining key with different values, l2 takes, precedence.

l2 will have unique values for the joining key.

right now I have tried this ugly piece of code:

l3 = []
rdict = {}
for i in range(len(l2)):
    rdict[l2[i][field]]=i
for d in l1: 
    l3.append(dict(d.items()+l2[rdict[d[field]]].items()))
return l3

as well as the solution from this SO question but that assumes only one index in all lists.

Thank you

Community
  • 1
  • 1
Andrew Blevins
  • 157
  • 1
  • 9

2 Answers2

3

Easy:

SELECT *
FROM l1, l2
WHERE l1.customer = l2.customer

...just kidding...

def join(t1,t2,column):
    result = []
    for entry in t2:
        for match in [d for d in t1 if d[column] == entry[column]]:
            result.append(dict((k,v) for k,v in entry.items()+match.items()))
    return result
Nate
  • 12,067
  • 5
  • 43
  • 60
1

Alternative answer...

def diff(d1, d2, key):
    if d1[key] != d2[key]:
        return d1
    new_keys = list(set(d2) - set(d1))
    for new_key in new_keys:
        d1[new_key] = d2[new_key]
    return d1

def join(l1, l2, key):
    l3 = l1
    for d2 in l2:
        l3 = map(lambda d1: diff(d1, d2, key), l3)
    return l3
U-DON
  • 2,044
  • 14
  • 14