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()
OrderedDict
decollections
list(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
set
clase 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 adict
no es hashaable.Si tuviera este problema, mi solución sería convertir cada uno
dict
en 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
dict
en forma de cadena es el formato JSON. Y Python tiene un módulo incorporado para JSON (llamado,json
por supuesto).El problema restante es que los elementos en a
dict
no están ordenados, y cuando Python conviertedict
a 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=True
cuando llamasjson.dumps()
.EDITAR: Esta solución suponía que un determinado
dict
podría tener una parte diferente. Si podemos suponer que cada unodict
con el mismo"id"
valor coincidirá entre sídict
con 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
dict
es 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 unmap
objeto.Dado que
id
es suficiente para detectar duplicados yid
es hashable: ejecútelos a través de un diccionario que tengaid
la 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.OrderedDict
lugar de undict
.Por otro lado, puede tener mucho sentido mantener los datos en un diccionario que utiliza la
id
tecla 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
pandas
Observe un poco diferente de la respuesta de aceptación.
drop_duplicates
comprobará todas las columnas en pandas, si todo es igual, la fila se descartará.Por ejemplo :
Si cambiamos el segundo
dict
nombre de John a Peterfuente
En python 3.6+ (lo que he probado), solo use:
Explicación: estamos mapeando
json.dumps
para codificar los diccionarios como objetos json, que son inmutables.set
entonces 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
list
antes 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
index
en atlen(values)
y contar hacia atrás, eso significa que siempre puede disminuirindex
si usteddel
o 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