问题描述
此问题的灵感来自于。我想从一个字典列表中找到一本字典,它应该包含所有字典中只包含一次的所有键/值对,或者所有字典都同意关联值。示例(取自上述发布):
This question is inspired by this question. I'd like to get a dictionary from a list of dictionaries that should contain all key/value pairs from all dictionaries that are either only contained once, or where all dictionaries agree on the associated value. Example (taken from the aforementioned posting):
dicts = [dict(a=3, b=89, d=2), dict(a=3, b=89, c=99), dict(a=3, b=42, c=33)]
print dict_itersection(dicts)
应该生成
{'a': 3, 'd': 2}
我目前的实现如下所示:
My current implementation looks like this:
import collections
def dict_intersection(dicts):
c=collections.defaultdict(set)
for d in dicts:
for a, b in d.iteritems():
c[a].add(b)
return {a: next(iter(b)) for a, b in c.iteritems() if len(b) == 1}
所以我的问题: >这可以更优雅吗?
So my question: Can this be done more elegantly?
Sidequestion:可以 next(iter(b))
更好地完成,而不修改底层字典(即不是 b.pop()
)?
Sidequestion: can next(iter(b))
be done better without modification of the underlying dictionary (i.e. not b.pop()
)?
推荐答案
到目前为止,所有的解决方案都假定所有的字典值是可以散列的。由于代码不会变慢,只有一点更复杂,没有这个假设,我会放弃它。这是一个适用于支持!=
的所有值的版本:
All solutions so far assume that all dictionary values are hashable. Since the code won't get slower and only little more complex without this assumption, I'd drop it. Here's a version that works for all values that support !=
:
def dict_intersection(dicts):
result = {}
conflicting = set()
for d in dicts:
for k, v in d.iteritems():
if k not in conflicting and result.setdefault(k, v) != v:
del result[k]
conflicting.add(k)
return result
设置冲突
将只包含字典键,这将始终是可以哈希的。
The set conflicting
will only contain dictionary keys, which will always be hashable.
这篇关于从词典列表中创建一个不相矛盾的词典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!