cómo uniqificar una lista de dict en python

Tengo una lista:

d = [{'x':1, 'y':2}, {'x':3, 'y':4}, {'x':1, 'y':2}] 

{'x':1, 'y':2} aparece más de una vez. Quiero eliminarlo de la lista. Mi resultado debería ser:

  d = [{'x':1, 'y':2}, {'x':3, 'y':4} ] 

Nota: la list(set(d)) no está funcionando aquí generando un error.

Si su valor es hashable esto funcionará:

 >>> [dict(y) for y in set(tuple(x.items()) for x in d)] [{'y': 4, 'x': 3}, {'y': 2, 'x': 1}] 

EDITAR:

Lo probé sin duplicados y parecía funcionar bien

 >>> d = [{'x':1, 'y':2}, {'x':3, 'y':4}] >>> [dict(y) for y in set(tuple(x.items()) for x in d)] [{'y': 4, 'x': 3}, {'y': 2, 'x': 1}] 

y

 >>> d = [{'x':1,'y':2}] >>> [dict(y) for y in set(tuple(x.items()) for x in d)] [{'y': 2, 'x': 1}] 

Los dictados no son hashables, así que no puedes ponerlos en un set. Un enfoque relativamente eficiente sería convertir los pares (key, value) en una tupla y hacer un hash de esas tuplas (no dude en eliminar las variables intermedias):

 tuples = tuple(set(d.iteritems()) for d in dicts) unique = set(tuples) return [dict(pairs) for pairs in unique] 

Si los valores no siempre son hashables, esto no es posible en ningún caso utilizando conjuntos y es probable que tenga que usar el enfoque O (n ^ 2) utilizando un control por elemento.

Evite todo este problema y use timbres nombrados en su lugar

 from collections import namedtuple Point = namedtuple('Point','x y'.split()) better_d = [Point(1,2), Point(3,4), Point(1,2)] print set(better_d) 

Un simple bucle:

 tmp=[] for i in d: if i not in tmp: tmp.append(i) tmp [{'x': 1, 'y': 2}, {'x': 3, 'y': 4}] 

Otra magia oscura (por favor no me gane):

 map(dict, set(map(lambda x: tuple(x.items()), d))) 

Tuple el dictado no estará bien, si el valor de un elemento de dict parece una lista.

p.ej,

 data = [ {'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {'a': 2, 'b': 3} ] 

utilizando [dict (y) para y en set (tuple (x.items ()) para x en datos)] obtendrá los datos únicos.

Sin embargo, la misma acción en dichos datos fallará:

 data = [ {'a': 1, 'b': 2, 'c': [1,2]}, {'a': 1, 'b': 2, 'c': [1,2]}, {'a': 2, 'b': 3, 'c': [3]} ] 

ignorar el rendimiento, json dumps/loads podría ser una buena opción.

 data = set([json.dumps(d) for d in data]) data = [json.loads(d) for d in data]