Допустим, у меня есть список словарей:
[
{'id': 1, 'name': 'john', 'age': 34},
{'id': 1, 'name': 'john', 'age': 34},
{'id': 2, 'name': 'hanna', 'age': 30},
]
и мне нужно получить список уникальных словарей (удалив дубликаты):
[
{'id': 1, 'name': 'john', 'age': 34},
{'id': 2, 'name': 'hanna', 'age': 30},
]
Может ли кто-нибудь помочь мне с наиболее эффективным способом достижения этого в Python?
python
dictionary
Limaaf
источник
источник
set(frozenset(i.items()) for i in list)
Ответы:
Так что сделайте временный дикт с ключом
id
. Это отфильтровывает дубликаты.values()
В Словаре будет списокВ Python2.7
В Python3
В Python2.5 / 2.6
источник
{str(v['flight'])+':'+str(v['lon'])+','+str(v['lat']): v for v in stream}.values()
Это просто создает уникальный ключ на основе ваших значений.'MH370:-21.474370,86.325589'
{(v['flight'], v['lon'], v['lat']): v for v in stream}.values()
OrderedDict
изcollections
list(OrderedDict((v['id'], v) for v in L).values())
или сортировки результирующего списка , если это работает лучше для васlist({str(i):i for i in L}.values())
Здесь мы используем str (i) для создания уникальной строки, представляющей словарь, который используется для фильтрации дубликатов.Обычный способ найти только общие элементы в наборе - использовать
set
класс Python . Просто добавьте все элементы в набор, затем преобразуйте набор в alist
, и, наконец, дубликаты исчезнут.Проблема, конечно, заключается в том, что a
set()
может содержать только хэшируемые записи, а adict
не хэшируемый.Если бы у меня возникла эта проблема, мое решение
dict
состояло бы в том, чтобы преобразовать каждую в строку, которая представляет собойdict
, затем добавить все строки в a,set()
затем прочитать значения строки как alist()
и преобразовать обратно вdict
.Хорошее представление
dict
в виде строки - это формат JSON. А в Python есть встроенный модуль для JSON (он называетсяjson
).Оставшаяся проблема заключается в том, что элементы в a
dict
не упорядочены, и когда Python преобразует ихdict
в строку JSON, вы можете получить две строки JSON, которые представляют собой эквивалентные словари, но не являются идентичными строками. Простое решение - передать аргументsort_keys=True
при вызовеjson.dumps()
.РЕДАКТИРОВАТЬ: Это решение предполагало, что данный
dict
может иметь любую часть отличается. Если мы можем предположить, что каждыйdict
с одинаковым"id"
значением будет совпадатьdict
с другим с одинаковым"id"
значением, то это излишне; Решение @ gnibbler будет быстрее и проще.РЕДАКТИРОВАТЬ: Теперь есть комментарий от Андре Лима, явно говоря, что если идентификатор является дубликатом, можно с уверенностью предположить, что все
dict
является дубликатом. Так что этот ответ излишний, и я рекомендую ответ @ gnibbler.источник
Если словари однозначно идентифицируются по всем элементам (идентификатор недоступен), вы можете использовать ответ, используя JSON. Следующее является альтернативой, которая не использует JSON и будет работать до тех пор, пока все значения словаря неизменны
источник
Вы можете использовать библиотеку numpy (работает только для Python2.x):
Чтобы это работало с Python 3.x (и последними версиями numpy), вам нужно преобразовать массив dicts в numpy массив строк, например
источник
TypeError: unorderable types: dict() > dict()
при выполнении этого в Python 3.5.Вот довольно компактное решение, хотя я подозреваю, что оно не особенно эффективно (мягко говоря):
источник
map()
вызовlist()
в Python 3, чтобы получить список обратно, иначе этоmap
объект.Так как
id
для обнаружения дубликатов достаточно, а дляid
хэширования - запустите их через словарь, в которомid
ключом является ключ. Значением для каждого ключа является исходный словарь.В Python 3
values()
не возвращает список; вам нужно будет обернуть всю правую часть этого выраженияlist()
, и вы можете написать экономически более выразительное выражение этого выражения для более глубокого понимания:Обратите внимание, что результат, скорее всего, будет не в том же порядке, что и оригинал. Если это требование, вы можете использовать
Collections.OrderedDict
вместоdict
.Кроме того, может иметь смысл сохранять данные в словаре, который
id
для начала использует ключ as.источник
выходы:
источник
Расширяя ответ John La Rooy ( Python - Список уникальных словарей ), делая его немного более гибким:
Функция вызова:
источник
Мы можем сделать с
pandas
Обратите внимание, немного отличается от принять ответ.
drop_duplicates
проверит все столбцы в пандах, если все одинаковые, то строка будет удалена.Например :
Если мы изменим 2-е
dict
имя с Джона на Питераисточник
В Python 3.6+ (что я тестировал) просто используйте:
Объяснение: мы сопоставляем
json.dumps
кодирование словарей как объектов json, которые являются неизменяемыми.set
затем может быть использован для создания итерируемой уникальной неизменяемой. Наконец, мы преобразуем обратно в наше словарное представление, используяjson.loads
. Обратите внимание, что изначально нужно сортировать по ключам, чтобы словари располагались в уникальной форме. Это действительно для Python 3.6+, так как словари упорядочены по умолчанию.источник
list
прежде чем делатьset
.Я суммировал мои любимые, чтобы попробовать:
https://repl.it/@SmaMa/Python-List-of-unique-dictionaries
источник
Быстрое и грязное решение заключается в создании нового списка.
источник
Я не знаю, хотите ли вы, чтобы идентификатор ваших dicts только в списке был уникальным, но если цель состоит в том, чтобы иметь набор dict, в котором уникальность находится на значениях всех ключей ... вы должны использовать кортежи key следующим образом в вашем понимании:
Надеюсь, это поможет вам или другому человеку, имеющему проблемы ....
источник
Здесь много ответов, поэтому позвольте мне добавить еще один:
источник
Довольно простой вариант:
источник
Ну, все ответы, упомянутые здесь, хороши, но в некоторых ответах можно столкнуться с ошибкой, если элементы словаря имеют вложенный список или словарь, поэтому я предлагаю простой ответ
источник
Вот реализация с небольшим объемом памяти за счет того, что она не такая компактная, как остальные.
вывод:
источник
index
atlen(values)
и считать в обратном направлении, это означает, что вы всегда можете уменьшить значение,index
независимо от того, есть выdel
или нет. напримерfor index in reversed(range(len(values))):
Это решение, которое я нашел:
В основном вы проверяете, присутствует ли идентификатор в списке, если он есть, удаляете словарь, если нет, добавляете идентификатор в список.
источник