Search code examples
pythondictionarynested

Easy way to compare values within all dicts in list of dicts?


Let's say I have a list of dicts, called mydict, that looks like like this:

[{'id': 6384,
  'character': 'Thomas A. Anderson / Neo',
  'credit_id': '52fe425bc3a36847f80181c1',
  'movie_id': 603},
 {'id': 2975,
  'character': 'Morpheus',
  'credit_id': '52fe425bc3a36847f801818d',
  'movie_id': 603},
 {'id': 530,
  'character': 'Trinity',
  'credit_id': '52fe425bc3a36847f8018191',
  'movie_id': 603},
 {'id': 1331,
  'character': 'Agent Smith',
  'credit_id': '52fe425bc3a36847f8018195',
  'movie_id': 603},
 {'id': 3165802,
  'character': 'MP Sergeant #1',
  'credit_id': '62ade87f4142910051c8e002',
  'movie_id': 28},
 {'id': 18471,
  'character': 'Self',
  'credit_id': '6259ed263acd2016291eef43',
  'movie_id': 963164},
 {'id': 74611,
  'character': 'Self',
  'credit_id': '6259ed37ecaef515ff68cae6',
  'movie_id': 963164}]

and I want to get all pairs of mydict['id'] values that have the same mydict['movie_id'] value - using only Python standard libraries. Essentially, returning

(6384, 2975)
(6384, 530)
(6384, 1331)
....
(18471, 74611)

Looping through every possible combination seems possible, but slow, with something like this.

results=[]
for i in mydict:
    for j in mydict:
        current = i['movie_id'] 
        next = j['movie_id']
    if current==next:
        results.append(i['id'], j['id'])

Is there a dictionary comprehension way to achieve the same result?


Solution

  • Consider using a collections.defaultdict() to group by movie_id. Then use itertools.combinations() to loop over them pairwise:

    from collections import defaultdict
    from itertools import combinations
    
    d = defaultdict(list)
    for movie in credits:
        d[movie['movie_id']].append(movie['id'])
    
    for group in d.values():
        for pair in combinations(group, 2):
            print(pair)
    

    For the given dataset, this outputs:

    (6384, 2975)
    (6384, 530)
    (6384, 1331)
    (2975, 530)
    (2975, 1331)
    (530, 1331)
    (18471, 74611)