繁体   English   中英

删除字典列表中的重复项

[英]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"]值与示例中所示的其他键值不同。 此实例称为副本。 我想从列表中删除重复的字典,但增加剩余字典的数量。

使用给定的信息,这个问题只能解决一半。 如果ModuleError键中包含的内容是可哈希的(例如字符串),则可以将它们用作字典的键。 您可以构造一个具有元组(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()

如果ModuleError由于元组本身不可散列,则此方法也可以工作。 但是,您将要确保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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM