简体   繁体   中英

pythonic way to find common key value pair among list of dict

I have a list of dictionaries.

alljson = [{'EchoTime': 0,
  'FlipAngle': 90,
  'MRAcquisitionType': '2D',
  'MagneticFieldStrength': 3,
  'Manufacturer': 'SIEMENS',
  'ManufacturerModelName': 'TrioTim',
  'RepetitionTime': 2,
  'ScanOptions': 'FS',
  'ScanningSequence': 'AP',
  'SequenceVariant': 'SK',
  'TaskName': 'Tom'},
 {'EchoTime': 0,
  'FlipAngle': 90,
  'MRAcquisitionType': '2D',
  'MagneticFieldStrength': 3,
  'Manufacturer': 'SIEMENS',
  'ManufacturerModelName': 'TrioTim',
  'RepetitionTime': 2,
  'ScanOptions': 'FS',
  'ScanningSequence': 'EP',
  'SequenceVariant': 'SK',
  'TaskName': 'fb'},
 {'EchoTime': 0,
  'FlipAngle': 90,
  'MRAcquisitionType': '2D',
  'MagneticFieldStrength': 3,
  'Manufacturer': 'SIEMENS',
  'ManufacturerModelName': 'TrioTim',
  'RepetitionTime': 2,
  'ScanOptions': 'FS',
  'ScanningSequence': 'EP',
  'SequenceVariant': 'HK', 
  'TaskName': 'Tom-loc'}]

Now i intend to find all common key value pairs from the list of dict. what would be the most pythonic way to do it.

Note: key and value both should match, and k:v pair should exist in all dict

I tried all solutions suggested here but given values are non hashable, none of the solution fully works.

any suggestions?

Convert each dictionary's list of items into a set, find the set intersection, and optionally convert the result back to a dictionary:

dict(set.intersection(*[set(d.items()) for d in alljson]))
#{'MRAcquisitionType': '2D', 'FlipAngle': 90, 'RepetitionTime': 2,
# 'ScanOptions': 'FS', 'ManufacturerModelName': 'TrioTim', 
# 'Manufacturer': 'SIEMENS', 'SequenceVariant': 'SK', 'EchoTime': 0, 
# 'MagneticFieldStrength': 3, 'ScanningSequence': 'EP'}

It depends on what you mean by "common" pairs, but assuming you mean 'pairs present in every dictionary', you can convert each dictionary to lists of tuples and then find the intersection of all of the lists:

list_of_lists = [x.items() for x in alljson]
common_pairs = set(list_of_lists[0]).intersection(*list_of_lists)
print(common_pairs)
>>> import operator as op
>>> reduce(op.iand, map(set, [d.items() for d in alljson]))
 reduce(lambda x, y: dict(set(x.items()).intersection(set(y.items()))), alljson)
{k : v for x in alljson for (k, v) in x.items()} 

This one is longer but to me it's intuitive:

count = {}
final = []

for dictionary in alljson:
  for key in dictionary:
    if key in count:
      count[key] += 1
    else:
      count[key] = 1

for key in count:
  if count[key] == len(alljson):
    final.append(key)

print final

Loop through alljson and count how many times each key shows up. Then return only the keys that show up in every dictionary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM