我的词典如下:
a = [{'un': 'a', 'id': "cd"}, {'un': 'b', 'id': "cd"},{'un': 'b', 'id': "cd"}, {'un': 'c', 'id': "vd"},
{'un': 'c', 'id': "a"}, {'un': 'c', 'id': "vd"}, {'un': 'a', 'id': "cm"}]
我需要通过'un'键找到字典的副本,例如这个{'un':'a','id':“cd”}和这个{'un':'a','id ':“cm”} dicts与键'un'的值重复第二,当找到重复项时我需要决定关于键'id'的第二个值的dict保持什么,例如我们保持dict的模式值“厘米”。
我已经做了第一步看到下面的代码:
from collections import defaultdict
temp_ids = []
dup_dict = defaultdict(list)
for number, row in enumerate(a):
id = row['un']
if id not in temp_ids:
temp_ids.append(id)
else:
tally[id].append(number)
使用此代码我或多或少能够找到重复列表的索引,也许还有其他方法可以做到这一点。而且我还需要下一步代码来决定dict保留什么以及省略什么。将非常感谢您的帮助。
答案 0 :(得分:1)
一般情况下,如果要在字典列表中查找重复项,则应按照重复字典保留在同一组中的方式对字典进行分类。为此,您需要根据dict
项目进行分类。现在,因为对于字典,订单不是一个重要的因素,您需要使用既可以清洗又不保持其容器顺序的容器。 frozenset()
是此任务的最佳选择。
示例:
In [87]: lst = [{2: 4, 6: 0},{20: 41, 60: 88},{5: 10, 2: 4, 6: 0},{20: 41, 60: 88},{2: 4, 6: 0}]
In [88]: result = defaultdict(list)
In [89]: for i, d in enumerate(lst):
...: result[frozenset(d.items())].append(i)
...:
In [91]: result
Out[91]:
defaultdict(list,
{frozenset({(2, 4), (6, 0)}): [0, 4],
frozenset({(20, 41), (60, 88)}): [1, 3],
frozenset({(2, 4), (5, 10), (6, 0)}): [2]})
在这种情况下,您可以根据'un'
键对词典进行分类,然后根据id
选择预期的项目:
>>> from collections import defaultdict
>>>
>>> d = defaultdict(list)
>>>
>>> for i in a:
... d[i['un']].append(i)
...
>>> d
defaultdict(<type 'list'>, {'a': [{'un': 'a', 'id': 'cd'}, {'un': 'a', 'id': 'cm'}], 'c': [{'un': 'c', 'id': 'vd'}, {'un': 'c', 'id': 'a'}, {'un': 'c', 'id': 'vd'}], 'b': [{'un': 'b', 'id': 'cd'}, {'un': 'b', 'id': 'cd'}]})
>>>
>>> keeps = {'a': 'cm', 'b':'cd', 'c':'vd'} # the key is 'un' and the value is 'id' should be keep for that 'un'
>>>
>>> [i for key, val in d.items() for i in val if i['id']==keeps[key]]
[{'un': 'a', 'id': 'cm'}, {'un': 'c', 'id': 'vd'}, {'un': 'c', 'id': 'vd'}, {'un': 'b', 'id': 'cd'}, {'un': 'b', 'id': 'cd'}]
>>>
在最后一行(嵌套列表推导)中,我们遍历聚合的dict项目,然后遍历值,并将这些项目保留在后面的值或条件i['id']==keeps[key]
中,这意味着我们将在id
词典中保留keeps
具有指定值的项目。
你可以将列表理解放在这样的东西上:
final_list = []
for key, val in d.items():
for i in val:
if i['id']==keeps[key]:
final_list.append(i)
请注意,由于列表推导的迭代已在C中执行,因此它比常规python循环和pythonic方式更快。但如果性能对您不重要,您可以使用常规方法。
答案 1 :(得分:1)
你几乎在正确的轨道上有一个默认的...这里大概是我会怎么写的。
from collections import defaultdict
a = [{'un': 'a', 'id': "cd"}, {'un': 'b', 'id': "cd"},{'un': 'b', 'id': "cd"}, {'un': 'c', 'id': "vd"}, {'un': 'c', 'id': "a"}, {'un': 'c', 'id': "vd"}, {'un': 'a', 'id': "cm"}]
items = defaultdict(list)
for row in a:
items[row['un']].append(row['id']) #make a list of 'id' values for each 'un' key
for key in items.keys():
if len(items[key]) > 1: #if there is more than one 'id'
newValue = somefunc(items[key]) #decided which of the list items to keep
items[key] = newValue #put that new value back into the dictionary