pythonic在dict列表中查找公共键值对的方法

Posted

技术标签:

【中文标题】pythonic在dict列表中查找公共键值对的方法【英文标题】:pythonic way to find common key value pair among list of dict 【发布时间】:2017-03-15 20:57:43 【问题描述】:

我有一个字典列表。

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']

现在我打算从 dict 列表中找到所有常见的键值对。 什么是最pythonic的方法。

注意:key 和 value 都应该匹配,并且 k:v 对应该存在于所有 dict 中

我尝试了here 建议的所有解决方案,但给定的值是不可散列的,没有一个解决方案完全有效。

有什么建议吗?

【问题讨论】:

您列表中的所有三个字典都是相同的。你到底想返回什么? 从我站的位置来看,你的价值观确实很容易散列。 @lordingtar 我已尝试在编辑中解释您的问题。现在的字典也不一样 【参考方案1】:

将每个字典的项目列表转换为集合,找到集合交集,并可选择将结果转换回字典:

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'

【讨论】:

我认为这并不完全正确。 EchoTime 出现 3 次,但在我的测试中返回 0。 @putonspectacles 再次检查。它在我的情况下被退回。 啊,我误读了这个问题,他只要求独特的出现。很喜欢这个,炫耀python扩展* @DYZ 它给了我错误说'dict' object is not callable @learnningprogramming 您必须在程序中的某处重新定义了dict。确保您没有类似 dict=... 的内容,然后重新启动您的解释器。【参考方案2】:

这取决于您所说的“常见”对的含义,但假设您的意思是“每个字典中都存在对”,您可以将每个字典转换为元组列表,然后找到所有列表的交集:

list_of_lists = [x.items() for x in alljson]
common_pairs = set(list_of_lists[0]).intersection(*list_of_lists)
print(common_pairs)

【讨论】:

【参考方案3】:
>>> import operator as op
>>> reduce(op.iand, map(set, [d.items() for d in alljson]))

【讨论】:

可爱,这里是关于操作符的文档:docs.python.org/2/library/operator.html FYR,函数 reduce 在 Python 3 中已被弃用。 @DYZ 我不会说已弃用,但是是的,它已从__builtins 移至functools 模块,因此它需要import。 docs.python.org/3.6/library/functools.html#functools.reduce【参考方案4】:
 reduce(lambda x, y: dict(set(x.items()).intersection(set(y.items()))), alljson)

【讨论】:

FYR,函数 reduce 在 Python 3 中已被弃用。【参考方案5】:
k : v for x in alljson for (k, v) in x.items() 

【讨论】:

【参考方案6】:

这个更长,但对我来说它很直观:

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

遍历 alljson 并计算每个键出现的次数。然后只返回出现在每个字典中的键。

【讨论】:

以上是关于pythonic在dict列表中查找公共键值对的方法的主要内容,如果未能解决你的问题,请参考以下文章

8.字典dict和解构-封装

HashMapHashTableConcurrentHashMap详解

Python基础

如何从键值对列表中创建 Spark Row

python dict 实现原理 2019-04-17

python字典中键值对的值为中文,打印成转义字符,怎么解决