【问题标题】:Find matching pairs of dictionaries in a list using Python使用 Python 在列表中查找匹配的字典对
【发布时间】:2019-07-10 13:42:20
【问题描述】:

在给定的列表中:

unmatched_items_array = [{'c': 45}, {'c': 35}, {'d': 5}, {'a': 3.2}, {'a': 3}]

查找所有“键”对并打印出来,如果没有找到给定字典的对,则打印出该字典。

到目前为止,我设法编写的内容有点像作品,但它会继续测试列表中的某些项目,即使它们已经过测试。不知道怎么解决。

for i in range(len(unmatched_items_array)):
        for j in range(i + 1, len(unmatched_items_array)):
            #  when keys are the same print matching dictionary pairs
            if unmatched_items_array[i].keys() == unmatched_items_array[j].keys():
                print(unmatched_items_array[i], unmatched_items_array[j])
                break
        #  when no matching pairs print currently processed dictionary
        print(unmatched_items_array[i])

输出:

{'c': 45} {'c': 35}
{'c': 45}
{'c': 35}
{'d': 5}
{'a': 3.2} {'a': 3}
{'a': 3.2}
{'a': 3}

输出应该是什么:

{'c': 45} {'c': 35}
{'d': 5}
{'a': 3.2} {'a': 3}

我在这里做错了什么?

【问题讨论】:

  • 你为什么需要它?将数据结构化为单对字典列表这一事实是您无法更改的吗?
  • 无法真正改变这一点。这就是数据进来的方式。但可以将其处理为其他东西。不知道哪种数据结构会更好。只要我最后得到匹配对

标签: python loops dictionary


【解决方案1】:

使用collections.defaultdict

例如:

from collections import defaultdict

unmatched_items_array = [{'c': 45}, {'c': 35}, {'d': 5}, {'a': 3.2}, {'a': 3}]
result = defaultdict(list)

for i in unmatched_items_array:
    key, _ = i.items()[0]
    result[key].append(i)          #Group by key. 

for _, v in result.items():        #print Result. 
    print(v)

输出:

[{'a': 3.2}, {'a': 3}]
[{'c': 45}, {'c': 35}]
[{'d': 5}]

【讨论】:

  • 你能解释一下在这种情况下使用defaultdict的好处吗?
  • 我猜 enumerate 是迭代 unmatched_items_array 的更好方法
  • 使用defaultdict ,您不需要检查结果变量中是否存在键。可以直接赋值。类似于setdefault(key, []).append(value)
  • @frankegoesdown 抱歉我不明白enumerate的用法
  • @Rakesh for i, d in enumerate(unmatched_items_array): for k, v in d.items(): result[k].append(d)
【解决方案2】:

itertools.groupby:

from itertools import groupby

unmatched_items_array = [{'d': 5}, {'c': 35}, {'a': 3}, {'a': 3.2}, {'c': 45}]

for v, g in groupby(sorted(unmatched_items_array, key=lambda k: tuple(k.keys())), lambda k: tuple(k.keys())):
    print([*g])

打印:

[{'a': 3}, {'a': 3.2}]
[{'c': 35}, {'c': 45}]
[{'d': 5}]

编辑:如果列表中的项目已经按键排序,那么您可以跳过 sorted() 调用:

for v, g in groupby(unmatched_items_array, lambda k: tuple(k.keys()) ):
    print([*g])

【讨论】:

  • 不得不说这看起来很复杂,我不太明白它是如何工作的,但是我得到的输出和你的不太一样。 [{'d': 5}] [{'c': 35}] [{'a': 3}, {'a': 3.2}] [{'c': 45}] 无法识别 'c '
  • 我做了,它找到了一对。 [{'a': 3}, {'a': 3.2}]
  • @michal-ko 真的吗?您是否向代码提供unmatched_items_array = [{'c': 45}, {'c': 35}, {'d': 5}, {'a': 3.2}, {'a': 3}]?使用此输入运行,我得到的输出为在我的答案中...两对 ca 和一个单个元素 d
  • 顺序略有不同,因为每次运行程序时它都会改变。但这应该没关系吧?如果我稍后对其进行排序。目前它看起来像 [{'d': 5}, {'c': 35}, {'a': 3}, {'a': 3.2}, {'c': 45}] 并且它只找到 ' a' 对并分别打印出其他的:/ 如果这能解释什么,我在 Python 3.5 上
  • @michal-ko 好的,我使用的是 Python 3.6。我更新了答案,试试新版本。
猜你喜欢
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多