Python - Список уникальных словарей, где каждое значение словаря представляет собой список - PullRequest
1 голос
/ 29 мая 2020

Допустим, у меня есть список словарей вроде этого:

[
 {'101': ['A','B'],
  '102': ['C'],
  '103': ['D'],
  '104': [],
  '105': [],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']},
 {'101': ['A'],
  '102': ['C'],
  '103': ['B'],
  '104': ['D'],
  '105': ['E'],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']},
{'101': ['A','B'],
  '102': ['C'],
  '103': ['D'],
  '104': [],
  '105': [],
  'deck': ['E','F', 'G', 'H', 'I', 'J', 'K', 'L']}
]

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

[
 {'101': ['A','B'],
  '102': ['C'],
  '103': ['D'],
  '104': [],
  '105': [],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']},
 {'101': ['A'],
  '102': ['C'],
  '103': ['B'],
  '104': ['D'],
  '105': ['E'],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}
]

Я пробовал

unique_solutions = list(set(val for dic in full_solutions_list for val in dic.values())) 

Но словарные значения типа «список» не хешируются.

Что было бы эффективным способом сделать это? (количество словарей относительно велико).

Ответы [ 2 ]

1 голос
/ 29 мая 2020

Вы пытаетесь перебрать значение словаря, что вызывает ошибку. Вы можете добавить dict в список, если значение еще не присутствует.

unique_solutions=[]
[unique_solutions.append(val) for val in lst if val not in unique_solutions]

Результат:

>>> print(unique_solutions)
[{'101': ['A', 'B'], '102': ['C'], '103': ['D'], '104': [], '105': [], 'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}, {'101': ['A'], '102': ['C'], '103': ['B'], '104': ['D'], '105': ['E'], 'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}]
1 голос
/ 29 мая 2020

Вы можете просто добавить dict к своему уникальному list, если он еще не содержится в нем (обратите внимание, что я предполагаю, что вы имели в виду, чтобы третий элемент имел 'E' в его списке deck , иначе это не было бы дубликатом):

x = [
 {'101': ['A','B'],
  '102': ['C'],
  '103': ['D'],
  '104': [],
  '105': [],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']},
 {'101': ['A'],
  '102': ['C'],
  '103': ['B'],
  '104': ['D'],
  '105': ['E'],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']},
{'101': ['A','B'],
  '102': ['C'],
  '103': ['D'],
  '104': [],
  '105': [],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}
]

unique_solutions = []
for d in x:
    if d not in unique_solutions:
        unique_solutions.append(d)

Или вы могли бы создать что-то вроде класса HashDict, который реализует хеши (в моем примере, используя кортежи, но это можно сделать по-разному ) и создайте set:

class HashDict(dict):
    def __init__(self, d):
        for k, v in d.items():
            self[k] = v

    def __hash__(self):
        return hash(tuple((k, tuple(v)) for k, v in self.items()))

hdx = [HashDict(d) for d in x]
unique_solutions = list(set(hdx))

Оба примера приводят к

>>> print(unique_solutions)
[{'101': ['A', 'B'], '102': ['C'], '103': ['D'], '104': [], '105': [], 'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}, {'101': ['A'], '102': ['C'], '103': ['B'], '104': ['D'], '105': ['E'], 'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...