-1

I have two lists of dict

listA = [{'id': 'abc', 'key1': '542696d8485b'}]
listB = [{'id': 'abc', 'key1': '542696d8485b'}, {'id': 'def', 'key1': '27348628grn'}]

I want to extract listC = [{'id': 'abc', 'key1': '542696d8485b'}]

i.e I want to find intersection based on 'id' field( based on any one field, assuming common items in list are exactly same ). Suggest me some efficient pythonic way...

How about something like

listA_set = set(item['id'] for item in listA)
listB_set = set(item['id'] for item in listB)
listC_set = listA_set & listB_set
listC = {item:listA[item] for item in listC_set}
Nish
  • 1,656
  • 1
  • 10
  • 19
  • 3
    What should the value of `key1` be if the `id` is the same but `key1` is different? – tobias_k Apr 12 '14 at 12:03
  • I think values mentioned were exactly same in both lists, still updated my question - I guess better now. – Nish Apr 12 '14 at 12:24
  • @Nish do you believe that using sets is better than lists? – Claudiu May 19 '20 at 09:13
  • Interesting how this one has multiple downvotes while https://stackoverflow.com/questions/33542997/python-intersection-of-2-lists-of-dictionaries/33543164 has the upvotes ... – Wolfgang Fahl Aug 11 '20 at 08:47

2 Answers2

11

Why not use list comprehension:

listA = [{'id': 'abc', 'key1': '542696d8485b'}]
listB = [{'id': 'abc', 'key1': '542696d8485b'}, {'id': 'def', 'key1': '27348628grn'}]

print [i for i in listA for j in listB if i['id']==j['id']]
sshashank124
  • 31,495
  • 9
  • 67
  • 76
2

You could just use a simple filtering

b_ids = set(d["id"] for d in listB)
result = [d for d in listA if d["id"] in b_ids]

assuming that you would like to keep the dictionary from listA when a possibly different dictionary with the same "id" value is in listB.

6502
  • 112,025
  • 15
  • 165
  • 265
  • What about my approach? - see edited question. You are iterating over complete listB ids. – Nish Apr 12 '14 at 12:43
  • @Nish: I've built a set from ids in `listB` so the `in` used in the list comprehension is O(1). Each of the two lists is iterated over in full just once, and the only case this wouldn't be needed is when one of the lists is empty. Your example is also iterating over the two full lists (when building the sets) and then does another iteration on the intersection. – 6502 Apr 12 '14 at 12:51