删除字典列表中的重复项

2024-09-24 22:25:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个字典列表,比如:

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


Tags: 实例modules列表字典timecounterrordict
3条回答

我相信这就是你需要的:

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

根据给定的信息,这个问题只能回答一半。如果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'}]

另外,请注意,这会将现有的dictionary对象放入一个新列表中。也就是说,运行此功能后,原始列表中的词典将被更新。为了避免这种情况,您可以将tupled_dictionary[key] = d更改为tupled_dictionary[key] = d.copy()。你知道吗

如果ModuleError是不可散列的,因为元组本身是可散列的,那么这种方法也可以工作。但是,您需要确保Module1 == Module2返回您期望的值。如果Module没有重写默认的类__eq__函数,那么等式只存在于对象id。(这可能是你想要的,很难说。)

这可能会起作用。你知道吗

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

相关问题 更多 >