Digamos que tengo una lista de diccionarios:
[
{'id': 1, 'name': 'john', 'age': 34},
{'id': 1, 'name': 'john', 'age': 34},
{'id': 2, 'name': 'hanna', 'age': 30},
]
y necesito obtener una lista de diccionarios únicos (eliminando los duplicados):
[
{'id': 1, 'name': 'john', 'age': 34},
{'id': 2, 'name': 'hanna', 'age': 30},
]
¿Alguien puede ayudarme con la forma más eficiente de lograr esto en Python?
python
dictionary
Limaaf
fuente
fuente

set(frozenset(i.items()) for i in list)Respuestas:
Así que haga un dict temporal con la clave siendo
id. Esto filtra los duplicados. Elvalues()del dict será la listaEn Python2.7
En Python3
En Python2.5 / 2.6
fuente
{str(v['flight'])+':'+str(v['lon'])+','+str(v['lat']): v for v in stream}.values()esto solo crea una clave única basada en sus valores. Me gusta'MH370:-21.474370,86.325589'{(v['flight'], v['lon'], v['lat']): v for v in stream}.values()OrderedDictdecollectionslist(OrderedDict((v['id'], v) for v in L).values())u ordenar la lista resultante si que funciona mejor para ustedlist({str(i):i for i in L}.values())Aquí usamos str (i) para crear una cadena única que represente el diccionario que se usa para filtrar los duplicados.La forma habitual de encontrar solo los elementos comunes en un conjunto es usar la
setclase de Python . Simplemente agregue todos los elementos al conjunto, luego convierta el conjunto a alist, y bam, los duplicados se han ido.El problema, por supuesto, es que a
set()solo puede contener entradas hashables, y adictno es hashaable.Si tuviera este problema, mi solución sería convertir cada uno
dicten una cadena que represente eldict, luego agregar todas las cadenas a yset()luego leer los valores de la cadena como alist()y convertirlos nuevamentedict.Una buena representación de una
dicten forma de cadena es el formato JSON. Y Python tiene un módulo incorporado para JSON (llamado,jsonpor supuesto).El problema restante es que los elementos en a
dictno están ordenados, y cuando Python conviertedicta una cadena JSON, puede obtener dos cadenas JSON que representan diccionarios equivalentes pero que no son cadenas idénticas. La solución fácil es pasar el argumentosort_keys=Truecuando llamasjson.dumps().EDITAR: Esta solución suponía que un determinado
dictpodría tener una parte diferente. Si podemos suponer que cada unodictcon el mismo"id"valor coincidirá entre sídictcon el mismo"id"valor, entonces esto es exagerado; La solución de @ gnibbler sería más rápida y fácil.EDITAR: Ahora hay un comentario de André Lima que dice explícitamente que si la identificación es un duplicado, es seguro asumir que el todo
dictes un duplicado. Entonces esta respuesta es exagerada y recomiendo la respuesta de @ gnibbler.fuente
En caso de que los diccionarios estén identificados únicamente por todos los elementos (el ID no está disponible), puede usar la respuesta con JSON. La siguiente es una alternativa que no utiliza JSON y funcionará siempre que todos los valores del diccionario sean inmutables
fuente
Puede usar la biblioteca numpy (solo funciona para Python2.x):
Para que funcione con Python 3.x (y versiones recientes de numpy), debe convertir una matriz de dictos en una matriz de cadenas numpy, por ejemplo
fuente
TypeError: unorderable types: dict() > dict()al hacer esto en Python 3.5.Aquí hay una solución razonablemente compacta, aunque sospecho que no es particularmente eficiente (por decirlo suavemente):
fuente
map()llamadalist()en Python 3 para recuperar una lista, de lo contrario es unmapobjeto.Dado que
ides suficiente para detectar duplicados yides hashable: ejecútelos a través de un diccionario que tengaidla clave. El valor de cada clave es el diccionario original.En Python 3,
values()no devuelve una lista; necesitará envolver todo el lado derecho de esa expresiónlist(), y puede escribir la carne de la expresión de manera más económica como una comprensión dict:Tenga en cuenta que el resultado probablemente no estará en el mismo orden que el original. Si ese es un requisito, puede usar un en
Collections.OrderedDictlugar de undict.Por otro lado, puede tener mucho sentido mantener los datos en un diccionario que utiliza la
idtecla como para comenzar.fuente
salidas:
fuente
Ampliando John La Rooy ( respuesta de Python - Lista de diccionarios únicos ), haciéndola un poco más flexible:
Función de llamada:
fuente
Podemos hacer con
pandasObserve un poco diferente de la respuesta de aceptación.
drop_duplicatescomprobará todas las columnas en pandas, si todo es igual, la fila se descartará.Por ejemplo :
Si cambiamos el segundo
dictnombre de John a Peterfuente
En python 3.6+ (lo que he probado), solo use:
Explicación: estamos mapeando
json.dumpspara codificar los diccionarios como objetos json, que son inmutables.setentonces puede usarse para producir un iterable de inmutables únicos . Finalmente, convertimos nuevamente a nuestra representación de diccionario usandojson.loads. Tenga en cuenta que inicialmente, uno debe ordenar por teclas para organizar los diccionarios en una forma única. Esto es válido para Python 3.6+ ya que los diccionarios están ordenados por defecto.fuente
listantes de hacerloset.He resumido mis favoritos para probar:
https://repl.it/@SmaMa/Python-List-of-unique-dictionaries
fuente
Una solución rápida y sucia es simplemente generando una nueva lista.
fuente
No sé si solo desea que la identificación de sus dictados en la lista sea única, pero si el objetivo es tener un conjunto de dict donde la unicidad está en los valores de todas las claves ... debe usar la clave de tuplas como esta en tu comprensión:
Espero que te ayude a ti u otra persona que tenga la preocupación ...
fuente
Aquí hay muchas respuestas, así que permítanme agregar otra:
fuente
Opción bastante sencilla:
fuente
Bueno, todas las respuestas mencionadas aquí son buenas, pero en algunas respuestas uno puede enfrentar un error si los elementos del diccionario tienen una lista anidada o un diccionario, por lo que propongo una respuesta simple
fuente
Heres una implementación con poca sobrecarga de memoria a costa de no ser tan compacta como el resto.
salida:
fuente
indexen atlen(values)y contar hacia atrás, eso significa que siempre puede disminuirindexsi usteddelo no. Por ejemplofor index in reversed(range(len(values))):Esta es la solución que encontré:
Básicamente verifica si la ID está presente en la lista, si es así, elimine el diccionario, si no, agregue la ID a la lista
fuente