使用Python在列表中查找匹配的字典对

3

在给定的列表中:

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

找到所有的“key”对,打印输出它们。如果给定的字典中没有配对,则打印出该字典。

目前我写的代码有点能用,但是它会不停地测试一些已经测试过的列表项。不确定如何修复它。

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}

我在这里做错了什么?

你为什么需要那个?将数据结构化为单对字典列表的事实是您无法更改的吗? - josoler
无法真正改变这一点。这就是数据的输入方式。但可以将其处理成其他形式。不知道哪种数据结构更好。只要最终得到匹配的对即可。 - michal-ko
2个回答

2

使用 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}]

1
请问您能解释一下在这种情况下使用defaultdict的优势吗? - buhtz
我猜枚举是迭代unmatched_items_array的更好方法。 - frankegoesdown
使用 defaultdict,您无需检查结果变量中是否存在键。您可以直接分配值。类似于 setdefault(key, []).append(value) 的工作方式。 - Rakesh
@Rakesh 对于字典d中的每个键值对k和v,执行以下操作: 将d附加到result[k] - frankegoesdown
但是你在做什么i索引值?它仍然没有被使用。 - Rakesh
显示剩余3条评论

1
使用 `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”。 - michal-ko
我这样做了,它找到了一对。 [{'a': 3}, {'a': 3.2}] - michal-ko
@michal-ko 真的吗?你是在提供 unmatched_items_array = [{'c': 45}, {'c': 35}, {'d': 5}, {'a': 3.2}, {'a': 3}] 给代码吗?使用这个输入运行,我得到的输出是:在我的答案中...有两对 ca 和一个单独的元素 d - Andrej Kesely
顺序每次运行程序都会略有不同,但这应该没关系吧?如果我后来要排序的话。目前看起来是[{'d': 5}, {'c': 35}, {'a': 3}, {'a': 3.2}, {'c': 45}],它只找到了'a'对,并将其他的分别打印出来 :/ 我使用的是Python 3.5,如果有什么解释的话。 - michal-ko
@michal-ko 好的,我正在使用Python 3.6。我更新了我的答案,请尝试新版本。 - Andrej Kesely
哇,现在它正常工作了!非常感谢您先生!看来在旧版本的Python中它的工作方式不同。 - michal-ko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接