删除词典列表中的重复项

时间:2016-03-15 22:03:36

标签: python list dictionary

我有一个词典列表,如:

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

5 个答案:

答案 0 :(得分:1)

根据给定的信息,这个问题只有一半是可以回答的。如果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下存在相等性。 (这可能是你想要的,很难说。)

答案 1 :(得分:1)

我相信这就是你所需要的:

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()

答案 2 :(得分:0)

这可能会起到作用。

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())

答案 3 :(得分:0)

你也可以看一下熊猫,因为你想要的几乎就是数据库操作:

with:

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

答案 4 :(得分:-1)

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
相关问题