Eliminar objetos JSON duplicados de la lista en python

Tengo una lista de dict donde un valor particular se repite varias veces, y me gustaría eliminar los valores duplicados.

Mi lista:

te = [ { "Name": "Bala", "phone": "None" }, { "Name": "Bala", "phone": "None" }, { "Name": "Bala", "phone": "None" }, { "Name": "Bala", "phone": "None" } ] 

Función para eliminar valores duplicados:

 def removeduplicate(it): seen = set() for x in it: if x not in seen: yield x seen.add(x) 

Cuando llamo a esta función obtengo generator object .

  

Cuando trato de recorrer el generador, obtengo TypeError: unhashable type: 'dict'

¿Hay alguna manera de eliminar los valores duplicados o iterar sobre el generador?

Puede eliminar fácilmente las claves duplicadas por la comprensión del diccionario, ya que el diccionario no permite claves duplicadas, como se muestra a continuación:

 te = [ { "Name": "Bala", "phone": "None" }, { "Name": "Bala", "phone": "None" }, { "Name": "Bala", "phone": "None" }, { "Name": "Bala", "phone": "None" }, { "Name": "Bala1", "phone": "None" } ] unique = { each['Name'] : each for each in te }.values() print unique 

Salida-

 [{'phone': 'None', 'Name': 'Bala1'}, {'phone': 'None', 'Name': 'Bala'}] 

Porque no se puede agregar un dict para set . De esta pregunta :

Estás intentando usar un dict como una clave para otro dict o en un set . Eso no funciona porque las claves tienen que ser hashable.

Como regla general, solo los objetos inmutables (cadenas, enteros, flotadores, frozensets, tuplas de inmutables) son hashable (aunque las excepciones son posibles).

 >>> foo = dict() >>> bar = set() >>> bar.add(foo) Traceback (most recent call last): File "", line 1, in  TypeError: unhashable type: 'dict' >>> 

En su lugar, ya estás usando if x not in seen , así que solo usa una lista:

 >>> te = [ ... { ... "Name": "Bala", ... "phone": "None" ... }, ... { ... "Name": "Bala", ... "phone": "None" ... }, ... { ... "Name": "Bala", ... "phone": "None" ... }, ... { ... "Name": "Bala", ... "phone": "None" ... } ... ] >>> def removeduplicate(it): ... seen = [] ... for x in it: ... if x not in seen: ... yield x ... seen.append(x) >>> removeduplicate(te)  >>> list(removeduplicate(te)) [{'phone': 'None', 'Name': 'Bala'}] >>> 

Aún puede usar un set para la detección de duplicados, solo necesita convertir el diccionario en algo que se pueda habilitar, como una tuple . Sus diccionarios se pueden convertir en tuplas por tuple(d.items()) donde d es un diccionario. Aplicando eso a su función de generador:

 def removeduplicate(it): seen = set() for x in it: t = tuple(x.items()) if t not in seen: yield x seen.add(t) >>> for d in removeduplicate(te): ... print(d) {'phone': 'None', 'Name': 'Bala'} >>> te.append({'Name': 'Bala', 'phone': '1234567890'}) >>> te.append({'Name': 'Someone', 'phone': '1234567890'}) >>> for d in removeduplicate(te): ... print(d) {'phone': 'None', 'Name': 'Bala'} {'phone': '1234567890', 'Name': 'Bala'} {'phone': '1234567890', 'Name': 'Someone'} 

Esto proporciona una búsqueda más rápida (promedio O (1)) que una list “vista” (O (n)). Si vale la pena el cálculo adicional de convertir cada dictado en una tupla, depende de la cantidad de diccionarios que tenga y de cuántos duplicados haya. Si hay muchos duplicados, una list “vista” crecerá bastante, y probar si un dictado ya se ha visto podría convertirse en una operación costosa. Esto podría justificar la conversión de la tupla; tendría que probarlo / perfilarlo.