![](/img/trans.png)
[英]python 2.6-removing and counting duplicates in a list of dictionaries effeciently
[英]Removing duplicates in a list of dictionaries
我有类似的字典列表:
dict_list = [
{"Module": abc, "Error": dgh, "Count": 12, Time: "kabs"},
{"Module": abc, "Error": dgh, "Count": 3, Time: "askdj"},
{"Module": aea, "Error": adsaw, "Count": 4, Time: "asna"
]
如您所见,每个字典具有相同的唯一键,但值相同或不同。 在某些情况下, dict2["Modules"] == dict1["Modules"]
和dict2["Errors"] == dict1["Errors"]
值与示例中所示的其他键值不同。 此实例称为副本。 我想从列表中删除重复的字典,但增加剩余字典的数量。
使用给定的信息,这个问题只能解决一半。 如果Module
和Error
键中包含的内容是可哈希的(例如字符串),则可以将它们用作字典的键。 您可以构造一个具有元组(Module, Error)
作为唯一键的中间词典,并检查其是否存在。 如果不存在,请存储字典。 如果存在,则增加Count
。 然后,该词典的值将包含原始列表的唯一条目以及累积的计数。
def merge_and_sum_counts(list_of_dictionaries):
tupled_dictionary = {}
for d in list_of_dictionaries:
key = (d['Module'], d['Error'])
if key not in tupled_dictionary:
tupled_dictionary[key] = d
else:
tupled_dictionary[key]['Count'] += d['Count']
return tupled_dictionary.values()
请注意,此函数并不关心每个词典中剩余的Time
(因为您没有提到它)。 下面给出示例用法。
list_of_dictionaries = [
{'Module': 'A', 'Error': 'A', 'Count': 5, 'Time': '22:34'},
{'Module': 'A', 'Error': 'A', 'Count': 3, 'Time': '21:33'},
{'Module': 'A', 'Error': 'B', 'Count': 2, 'Time': '15:31'},
{'Module': 'B', 'Error': 'A', 'Count': 1, 'Time': '07:59'},
{'Module': 'B', 'Error': 'A', 'Count': 7, 'Time': '10:45'},
{'Module': 'B', 'Error': 'B', 'Count': 9, 'Time': '15:45'},
]
print merge_and_sum_counts(list_of_dictionaries)
# [{'Count': 8, 'Time': '07:59', 'Module': 'B', 'Error': 'A'},
# {'Count': 2, 'Time': '15:31', 'Module': 'A', 'Error': 'B'},
# {'Count': 8, 'Time': '22:34', 'Module': 'A', 'Error': 'A'},
# {'Count': 9, 'Time': '15:45', 'Module': 'B', 'Error': 'B'}]
另外,请注意,这会将现有字典对象放入新列表中。 意思是,运行此功能后,原始列表中的词典将被更新。 为了避免这种情况,可以将tupled_dictionary[key] = d
更改为tupled_dictionary[key] = d.copy()
。
如果Module
和Error
由于元组本身不可散列,则此方法也可以工作。 但是,您将要确保Module1 == Module2
返回您期望的值。 如果Module
没有覆盖默认的__eq__
类函数,则相等性仅存在至对象id
。 (可能是您想要的,这很难说。)
我相信这是您需要的:
no_duplicates = {}
for d in dict_list:
k = (d["Module"], d["Error"])
if k in no_duplicates:
no_duplicates[k]["Count"] += d['Count']
else:
no_duplicates[k] = d # or d.copy() if you need to keep d untouched
no_duplicates = no_duplicates.values()
这可能会完成工作。
no_duplicates = {}
for d in dict_list:
# Generate your unique key
k = (d["Module"], d["Error"])
try:
# Add if already exists.
no_duplicates[k]["Count"] += 1
except KeyError:
# Create a new one if not.
no_duplicates[k] = d
d["Count"] = 1
# Generate the new list (Works for python 2 and 3)
no_duplicates_list = list(no_duplicates.values())
您将创建一个没有重复项的新字典,并将键设置为您希望没有重复项的值。 例如(d["Module"], d["Error"])
。 然后,如果已经存在,则增加计数。 如果不是,则在字典中创建一个新条目。
但是,如果您拥有的新密钥多于重复项,这将更加有效,因为将引发更少的异常:
no_duplicates = {}
for d in dict_list:
k = (d["Module"], d["Error"])
# Set count to 0
d["Count"] = 0
# Set and increase count at once
no_duplicates.setdefault(k, d)["Count"] += 1
no_duplicates_list = list(no_duplicates.values())
更新:
如果您不想重置计数,请使用以下代码:
no_duplicates = {}
for d in dict_list:
# Generate your unique key
k = (d["Module"], d["Error"])
try:
# Add if already exists.
no_duplicates[k]["Count"] += d["Count"]
except KeyError:
# Create a new one if not.
no_duplicates[k] = d
# Generate the new list (Works for python 2 and 3)
no_duplicates_list = list(no_duplicates.values())
要么
no_duplicates = {}
for d in dict_list:
k = (d["Module"], d["Error"])
# Set and increase count at once
no_duplicates.setdefault(k, d)["Count"] += 1
no_duplicates_list = list(no_duplicates.values())
您还可以看看pandas,因为您想要的几乎是数据库操作:
与:
dict_list=[{'Time': 'kabs', 'Count': 12, 'Error': 1, 'Module': 1},
{'Time': 'askdj', 'Count': 3, 'Error': 1, 'Module': 1},
{'Time': 'asna', 'Count': 4, 'Error': 2, 'Module': 2}]
pandas.DataFrame(dict_list).groupby(['Module','Error'])['Count'].sum()
给出:
Module Error
1 1 15
2 2 4
list_d = [{"Module":'abc',"Error":'dgh',"Count":'fff','Time':"kabs"},
{"Module":'abc',"Error":'dgh',"Count":'adak','Time':"askdj"},
{ "Module":'aea',"Error":'adsaw',"Count":'asa','Time':"asna"}]
no_duplicate = {}
for index, d in enumerate(list_d):
key = d['Module'].lower() +'-'+ d['Error'].lower()
if key not in no_duplicate:
no_duplicate[key] = [index,1]
else:
no_duplicate[key][1] += 1
output = []
for key,value in no_duplicate.items():
index = value[0]
count = value[1]
if count >=2:
list_d[index]['count'] = count
output.append(list_d[index])
print output
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.