2011-10-07 41 views
5

Tengo un archivo CSV con varias entradas. Ejemplo csv:Python: eliminar entradas duplicadas de CSV

user, phone, email 
joe, 123, [email protected] 
mary, 456, [email protected] 
ed, 123, [email protected] 

Estoy tratando de eliminar los duplicados por una columna específica de la CSV sin embargo, con el código de abajo Recibo un "índice de la lista fuera de alcance". Pensé que al comparar row[1] con newrows[1] encontraría todos los duplicados y solo volvería a escribir las entradas únicas en file2.csv. Sin embargo, esto no funciona y no puedo entender por qué.

f1 = csv.reader(open('file1.csv', 'rb')) 
    newrows = [] 
    for row in f1: 
     if row[1] not in newrows[1]: 
      newrows.append(row) 
    writer = csv.writer(open("file2.csv", "wb")) 
    writer.writerows(newrows) 

Mi resultado final es tener una lista que mantiene la secuencia del archivo (set no va a funcionar ... ¿verdad?), Que debería tener este aspecto:

user, phone, email 
joe, 123, [email protected] 
mary, 456, [email protected] 
+0

creo una base de datos sería muy útil en este caso. Python trabaja OOB con SQLite, ¿sabes? – NullUserException

+0

cuando algo no funciona, siempre necesita describir lo que sucedió. Es un error? ¿no es nada? ¿es lo incorrecto? –

+0

Lo hice ... mi código actualmente produce un índice de lista fuera de rango. Esto no tiene sentido ya que está buscando la segunda "columna" con la fila [1]. – serk

Respuesta

8

row[1] se refiere a la segunda columna en la fila actual (teléfono). Eso está bien en todo. Sin embargo, newrows.append(row) agrega la fila completa a la lista.

Al marcar row[1] in newrows está marcando el número de teléfono individual con una lista de filas completas. Pero eso no es lo que quieres hacer. Debes consultar una lista o un conjunto de números de teléfono. Para eso, es probable que desee realizar un seguimiento de las filas y un conjunto de los números de teléfono observados.

Algo así como:

f1 = csv.reader(open('file1.csv', 'rb')) 
writer = csv.writer(open("file2.csv", "wb")) 
phone_numbers = set() 
for row in f1: 
    if row[1] not in phone_numbers: 
     writer.writerow(row) 
     phone_numbers.add(row[1]) 
+0

Esto funcionó. ¡Gracias! Pensé que 'set' no funcionaría porque no mantendría el orden de la salida correcta. ¿Funcionaría esto si utilizara la lista 'newrows' y acabara de modificar' append (row) 'en' writerow'? – serk

+0

@serk, configura las obras porque no me importa el orden. Solo controlo si hay cosas en él. Sí, agregar a la lista funcionará bien. –

+1

Por cierto, si de hecho está eliminando números de teléfono duplicados para, por ejemplo, una base de datos de telemarking, tiene el potencial de realmente perder sus listas de llamadas de esa manera. Y a veces los números de teléfono que están más adelante en su archivo de lector serán ** más nuevos ** y números de teléfono más precisos que los mismos números de teléfono que haya encontrado anteriormente en el archivo del lector, ya que fueron escritos en el archivo luego el mismo número de teléfono más adelante en el archivo del lector. – DevPlayer

Cuestiones relacionadas