我有类似的字典清单:
sel_list = [{'a': 8}, {'a': 4}, {'a': 4}, {'b': 8}, {'b': 9}]
我想删除重复的字典,如果多个字典具有相同的键但值不同,则选择该值较高的字典。
赞:
sel_list = [{'a': 8}, {'b': 9}]
我尝试过:
[i for n, i in enumerate(sel_list) if i not in sel_list[n + 1:]]
其结果为:
[{'a': 8}, {'a': 4}, {'b': 8}, {'b': 9}]
我该怎么做才能达到目标?
答案 0 :(得分:7)
我们可以通过构造一个字典来做到这一点,该字典通过每次选择最大值来“折叠”值。喜欢:
dummy = object()
maximums = {}
for subd in sel_list:
for k, v in subd.items():
cur = maximums.get(k, dummy)
if cur is dummy or v > cur:
maximums[k] = v
result = [{k: v} for k, v in maximums.items()]
因此,我们迭代列表中的 key-value 对字典,并在关键字不存在或当前值不存在的情况下,每次更新maximums
字典更少。
在此迭代步骤之后,我们生成了具有最大键值对的字典列表。
此方法适用于所有可以排序的类型(数字,字符串等),并且键应该是可散列的,但是这种假设成立,因为在字典列表中,键是已经散列了。
此外,它会忽略空字典,并且通过将它们视为独立的键值对来处理具有多个键值对的字典,因此它的功能相当强大。
您还可以决定直接使用maximums
:一个字典,其中包含原始列表中的所有键,并将这些键与列表中看到的最大值相关联。
答案 1 :(得分:2)
免责声明:我不确定我的解决方案有多少 Pythonic
假设{{1 }}仅包含一个键,值对。 (即dict
在这里不是有效的字典)
{"a":2,"b":3}
答案 2 :(得分:1)
代码:
from collections import defaultdict
sel_list = [{'a': 8}, {'a': 4}, {'a': 4}, {'b': 8}, {'b': 9}]
results = defaultdict(list)
for element in sel_list:
for key, value in element.items():
results[key].append(value)
for item_key, item_value in results.items():
results[item_key] = max(item_value)
print(results)
输出:
defaultdict(<class 'list'>, {'b': 9, 'a': 8})
答案 3 :(得分:0)
您可以通过reduce
是您的状态的dict
操作来做到这一点:
from functools import reduce
from itertools import chain
sel_list = [{'a': 8}, {'a': 4}, {'a': 4}, {'b': 8}, {'b': 9}]
# function to aggregate max value item into a `dict`
def agg(d, kv):
k, v = kv
d[k] = max(d.get(k, v), v)
return d
# concatenate all items from all `dict`s
sel_items = chain.from_iterable(map(dict.items, sel_list))
# aggregate using a single `dict` which implicitly holds required semantics
result = reduce(agg, sel_items, {}) # {'a': 8, 'b': 9} <-- better?
要获取输出格式(相对于dict
IMO,不是不利的):
formatted = [dict((item, )) for item in result.items()]
dict
的语义对您有利。我认为这对您来说是一个更好的数据结构。