简体   繁体   English

从无序字典列表中删除重复项

[英]Remove duplicates from a list of a list of unordered dictionaries

Consider the following:考虑以下:

[
  [
    {'name': 'fred', 'score': 19},
    {'name': 'frank', 'score': 100},
    {'name': 'bob', 'score': 99}
  ],
  [
    {'name': 'frank', 'score': 100},
    {'name': 'fred', 'score': 19},
    {'name': 'bob', 'score': 99}
  ],
  [
    {'name': 'bob', 'score': 99},
    {'name': 'frank', 'score': 100},
    {'name': 'fred', 'score': 19}
  ],
  [
    {'name': 'fred', 'score': 19},
    {'name': 'frank', 'score': 100},
    {'name': 'stu', 'score': 69}
  ]
]

Ignoring the order of the dictionaries within each list, how can duplicates be removed such that the output would be only two of the lists: one with bob and one with stu?忽略每个列表中字典的顺序,如何删除重复项,以便输出只有两个列表:一个是 bob,另一个是 stu?

Output something like:输出类似:

[
  [
    {'name': 'fred', 'score': 19},
    {'name': 'frank', 'score': 100},
    {'name': 'bob', 'score': 99}
  ],
  [
    {'name': 'fred', 'score': 19},
    {'name': 'frank', 'score': 100},
    {'name': 'stu', 'score': 69}
  ]
]

You could try something like this你可以试试这样的

dict_list =   [[{'name': 'fred', 'score': 19},
  {'name': 'frank', 'score': 100},
  {'name': 'bob', 'score': 99}],
 [{'name': 'frank', 'score': 100},
  {'name': 'fred', 'score': 19},
  {'name': 'bob', 'score': 99}],
 [{'name': 'bob', 'score': 99},
  {'name': 'frank', 'score': 100},
  {'name': 'fred', 'score': 19}],
 [{'name': 'fred', 'score': 19},
  {'name': 'frank', 'score': 100},
  {'name': 'stu', 'score': 69}]]

# create list of names you've seen before
name_lists = []
# create lists of unique lists
unique_lists = []

# loop over each list you have
for L in dict_list:

    # get list of names
    names = [i['name'] for i in L]

    # check if you've seen this set of names before
    if set(names) not in [set(n) for n in name_lists]:
        print(names)
        # save these names
        name_lists.append(names)
        # add this list to your list of unique names
        unique_lists.append(L)

Output:输出:

['fred', 'frank', 'bob']
['fred', 'frank', 'stu']

unique_lists Output: unique_lists输出:

[[{'name': 'fred', 'score': 19},
  {'name': 'frank', 'score': 100},
  {'name': 'bob', 'score': 99}],
 [{'name': 'fred', 'score': 19},
  {'name': 'frank', 'score': 100},
  {'name': 'stu', 'score': 69}]]

Note that this method will save only the scores for the first set of unique names and discard scores when the set of names is duplicated.请注意,此方法将仅保存第一组唯一名称的分数,并在名称组重复时丢弃分数。 If it is expected that the same names may have different scores, you may want to save every unique set of scores.如果预计相同的名称可能会有不同的分数,您可能希望保存每组唯一的分数。 In this case, you can follow the method given by PacketLoss below:在这种情况下,您可以按照以下 PacketLoss 给出的方法进行操作:

name_lists = []
unique_lists = []


for di, d in enumerate(dict_list):

    # get list of name, score tuples
    r = [(i['name'], i['score']) for i in d]
    # sort tuples alphabetically by name
    r.sort(key=lambda tup: tup[0])

    # check if these names and scores have been seen before
    if r not in name_lists:
        name_lists.append(r)
        unique_lists.append(dict_list[di])

Due to the ordering being off, a simple == will not match, we can work around this by gathering the data, sorting it as a list of tuples and checking if the match has been seen before.由于排序被关闭,简单的==将不匹配,我们可以通过收集数据、将其排序为元组列表并检查之前是否已经看到匹配来解决这个问题。

data = [[{'name': 'fred', 'score': 19},
  {'name': 'frank', 'score': 100},
  {'name': 'bob', 'score': 99}],
 [{'name': 'frank', 'score': 100},
  {'name': 'fred', 'score': 19},
  {'name': 'bob', 'score': 99}],
 [{'name': 'bob', 'score': 99},
  {'name': 'frank', 'score': 100},
  {'name': 'fred', 'score': 19}],
 [{'name': 'fred', 'score': 19},
  {'name': 'frank', 'score': 100},
  {'name': 'stu', 'score': 69}]]

seen = list()
result = list()

for idx, d in enumerate(data):
    r = [(i['name'], i['score']) for i in d]
    r.sort(key=lambda tup: tup[0])
    if r not in seen:
        seen.append(r)
        result.append(data[idx])

With this method, we are checking that both the scores and names are a complete match, meaning if one score in a duplicate changed to 98 it would no longer be counted as a duplicate.使用这种方法,我们会检查分数和名称是否完全匹配,这意味着如果重复中的一个分数更改为98 ,它将不再被视为重复。

Output:输出:

[[{'name': 'fred', 'score': 19}, {'name': 'frank', 'score': 100}, {'name': 'bob', 'score': 99}], [{'name': 'fred', 'score': 19}, {'name': 'frank', 'score': 100}, {'name': 'stu', 'score': 69}]]

Output with modifying scores in data:修改数据分数的输出:

data = [[{'name': 'fred', 'score': 19},
  {'name': 'frank', 'score': 100},
  {'name': 'bob', 'score': 99}],
 [{'name': 'frank', 'score': 100},
  {'name': 'fred', 'score': 19},
  {'name': 'bob', 'score': 99}],
 [{'name': 'bob', 'score': 98},
  {'name': 'frank', 'score': 100},
  {'name': 'fred', 'score': 19}],
 [{'name': 'fred', 'score': 19},
  {'name': 'frank', 'score': 100},
  {'name': 'stu', 'score': 69}]]

[[{'name': 'fred', 'score': 19}, {'name': 'frank', 'score': 100}, {'name': 'bob', 'score': 99}], [{'name': 'bob', 'score': 98}, {'name': 'frank', 'score': 100}, {'name': 'fred', 'score': 19}], [{'name': 'fred', 'score': 19}, {'name': 'frank', 'score': 100}, {'name': 'stu', 'score': 69}]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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