Как удалить дубликаты в списке словарей, содержащих списки? - PullRequest
0 голосов
/ 30 апреля 2019

У меня есть список словарей, где каждый словарь имеет список в себе:

    [{'author': 'Stephen King', 'books': ['The stand', 'The 
    Outsider']}, {'author': 'Ernest Hemingway', 'books': ['A 
    Moveable Feast', 'The sun Also Rises']},{'author': 'Stephen 
    King', 'books': ['The stand', 'The Outsider']}]

Я пробовал большинство способов удаления дубликатов в списке словарей, но пока они не работают из-за массива внутри словаря.

Цель состоит в том, чтобы удалить дубликаты в списке словарей, в которых каждый словарь сам по себе имеет список

Ожидаемый результат в приведенных выше данных должен быть:

    [{'author': 'Stephen King', 'books': ['The stand', 'The 
    Outsider']}, {'author': 'Ernest Hemingway', 'books': ['A 
    Moveable Feast', 'The sun Also Rises']}]

Ответы [ 3 ]

0 голосов
/ 30 апреля 2019
dicts = [{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}, {'author': 'Ernest Hemingway', 'books': ['A Moveable Feast', 'The sun Also Rises']},{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}]

def remove(dicts):
    for i in range(len(dicts)):
        if dicts[i] in dicts[i+1:]:
            dicts.remove(dicts[i])
            return remove(dicts)
        else:
            return dicts

print (remove(dicts))

вывод:

[{'author': 'Ernest Hemingway', 'books': ['A Moveable Feast', 'The sun Also Rises']}, {'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}]
0 голосов
/ 30 апреля 2019

Вы должны написать некоторый код, который может преобразовать словарь в вашем формате в хешируемый объект. Тогда нормальный код дедупликации (с использованием set) будет работать:

data = [{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']},
        {'author': 'Ernest Hemingway', 'books': ['A Moveable Feast', 'The sun Also Rises']},
        {'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}]

seen = set()
result = []
for dct in data:
    t = (dct['author'], tuple(dct['books'])) # transform into something hashable
    if t not in seen:
        seen.add(t)
        result.append(dct)

Этот код предполагает, что в ваших словарях есть только ключи 'author' и 'books', и ничего больше. Если вы хотите быть более общим и поддерживать другие ключи и значения, вы можете немного расширить логику. Вот альтернативное вычисление t, которое будет поддерживать произвольные ключи (при условии, что они все сопоставимы) и любое количество списков среди значений:

t = tuple((k, tuple(v) if insinstance(v, list) else v) for k, v in sorted(dct.items())
0 голосов
/ 30 апреля 2019

Это один подход.

Пример:

data = [{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}, {'author': 'Ernest Hemingway', 'books': ['A Moveable Feast', 'The sun Also Rises']},{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}]

checkVal = set()
result = []
for item in data:
    if item["author"] not in checkVal:   #Check if author & books in checkVal 
        result.append(item)              #Append result.
        checkVal.add(item["author"])     #Add author & books to checkVal 
print(result)

Вывод:

[{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']},
 {'author': 'Ernest Hemingway',
  'books': ['A Moveable Feast', 'The sun Also Rises']}]

Редактировать в соответствии с комментарием - отметьте author и books

checkVal = set()
result = []
for item in data:
    c = tuple(item["books"] + [item["author"]])
    if c not in checkVal:   #Check if author in checkVal 
        result.append(item)              #Append result.
        checkVal.add(c)     #Add author to checkVal 
pprint(result)
...