2010-11-12 21 views
12

Tengo una lista de objetos y tengo una tabla db llena de registros. Mi lista de objetos tiene un atributo de título y quiero eliminar cualquier objeto con títulos duplicados de la lista (dejando el original).Eliminar duplicados en la lista de objetos con Python

Luego quiero verificar si mi lista de objetos tiene duplicados de los registros en la base de datos y, de ser así, eliminar esos elementos de la lista antes de agregarlos a la base de datos.

He visto soluciones para eliminar duplicados de una lista como esta: myList = list(set(myList)), pero no estoy seguro de cómo hacer eso con una lista de objetos?

Necesito mantener el orden de mi lista de objetos también. También estaba pensando que tal vez podría usar difflib para verificar las diferencias en los títulos.

+4

Paso 1. Buscar. Esta redacción exacta se usa cada semestre en la clase de programación de Python. Por favor busca –

+0

__dejando el original__, ¿qué significa esto? porque si, como dijiste, quieres __mantener el pedido__ de la lista para que la primera aparición de un objeto duplicado en la lista sea la derecha original? – mouad

+0

Sí, solo quise eliminar todos los duplicados excepto el original. @ S. Lot, busqué mucho y no encontré nada, por eso vine aquí. ¿Puedes citar un ejemplo que aborde este problema exacto? Me gustaría verlo – imns

Respuesta

28

El set(list_of_objects) sólo eliminará los duplicados si sabes lo que es un duplicado, es decir, tendrá que definir una singularidad de un objeto.

Con el fin de hacer eso, tendrá que hacer el objeto hashable. Es necesario definir tanto el método __hash__ y __eq__, aquí es cómo:

http://docs.python.org/glossary.html#term-hashable

Sin embargo, es probable que sólo se necesita definir __eq__ método.

EDITAR: Cómo implementar el método __eq__:

Usted necesita saber, como ya he mencionado, la definición singularidad de su objeto. Suponemos que tenemos un Libro con atributos autor_nombre y título que su combinación es única, (entonces, podemos tener muchos libros creados por Stephen King, y muchos libros llamados The Shining, pero solo un libro llamado The Shining por Stephen King), luego la implementación es el siguiente:

def __eq__(self, other): 
    return self.author_name==other.author_name\ 
      and self.title==other.title 

del mismo modo, así es como a veces me implementar el __hash__ método:

def __hash__(self): 
    return hash(('title', self.title, 
       'author_name', self.author_name)) 

usted puede comprobar que si se crea una lista de 2 libros con un mismo autor y el título, el libro los objetos serán iguales (con el operador is) y igual (con el operador ==). Además, cuando se usa set(), se eliminará un libro.

EDITAR: Esta es una vieja anwser mío, pero sólo ahora cuenta de que tiene el error que se corrige con tachado en el último párrafo: objetos con el mismo hash() no dará True en comparación con is . La capacidad de acceso de objeto se usa, sin embargo, si tiene la intención de usarlos como elementos del conjunto o como claves en el diccionario.

+0

Bueno, no sabía sobre '__hash__' y' __eq__'. ¿Algún ejemplo sobre cómo implementar '__eq__'? – imns

+0

ver la edición anterior – vonPetrushev

6

Como no son aptas para colgar, no puede usar un juego directamente. Los títulos deberían ser sin embargo.

Aquí está la primera parte.

seen_titles = set() 
new_list = [] 
for obj in myList: 
    if obj.title not in seen_titles: 
     new_list.append(obj) 
     seen_titles.add(obj.title) 

Sin embargo, vas a tener que describir qué base de datos/ORM estás utilizando para la segunda parte.

+0

Estoy usando mysql con sqlobject. – imns

+0

@bababa por favor actualice la pregunta para que otras personas lo vean también. – aaronasterling

+0

@bababa, no veo una buena manera de hacer esto usando sqlobject (es decir, sin extraer cada objeto de la base de datos en una consulta o hacer una consulta por objeto) así que esperaré un momento y luego publicaré eso si alguien no conoce sqlobject mejor de lo que yo no aparece. – aaronasterling

1

Esto parece bastante escaso:

new_dict = dict() 
for obj in myList: 
    if obj.title not in new_dict: 
     new_dict[obj.title] = obj 
0

Sus Freinds muy fácil: -

a = [5,6,7,32,32,32,32,32,32,32,32]

una = lista (conjunto (a))

de impresión (a)

[5,6,7,32] 

eso es todo! :)

+5

No se puede hacer esto en una lista que contiene objetos. –

0

Si desea conservar el orden original usarlo:

seen = {} 
new_list = [seen.setdefault(x, x) for x in my_list if x not in seen] 

Si no se preocupan de ordenar luego usarlo:

new_list = list(set(my_list)) 
Cuestiones relacionadas