2011-03-23 7 views
6

Duplicar posibles:
Remove items from a list while iterating in Pythonproblema al eliminar elementos de la lista en un bucle for (pitón)

Hola estoy teniendo un problema que parece que no puede eliminar elementos mientras iteración a través de una lista en Python , Esto es lo que tengo: se debe eliminar un título si un usuario ingresa n o N cuando se le pregunta si desea eliminarlo en el ciclo for, el problema es que cuando todo está listo los elementos siguen allí y ninguno tiene eliminado ...

titles_list = ["English", "Math", "History", "IT", "Biology", "Spanish"] 

    for title in titles_list: 
     print "Do you want to keep the title:", title , "\n or Delete it ? Input Y for keep, N for Delete " 
     Question = raw_input() 
     if str(Question.upper) == "N": 
      titles_list.remove(title) 

print titles_list 
+0

También un DUP de [extraño comportamiento de Python en bucle o listas] (http : //stackoverflow.com/q/742371/76705). Y la solución de división de listas parece ser más pitonica. –

Respuesta

10

El siguiente código solucionará su problema. Tienes que iterar sobre una copia de la lista. No puede eliminar elementos de la lista sobre la que está iterando.

import copy 

def main(): 
    titles_list = ["English", "Math", "History", "IT", "Biology", "Spanish"] 
    titles_list_orig = copy.deepcopy(titles_list) 

    for title in titles_list_orig: 
     print "Do you want to keep the title:", title , "\n or Delete it? Input Y for keep, N for Delete " 
     Question = raw_input() 
     if str(Question.upper()) == "N": 
      titles_list.remove(title) 

    print titles_list 
+0

gracias: D utilicé el empalme porque tiene menos líneas pero me lleva a necesitar copiarlo gracias – RY4N

+0

No es necesario copiarlo, simplemente itere sobre él en reversa para que las eliminaciones no afecten los elementos que ve al iterar. – ncoghlan

+1

@ncoghlan: ¿puede explicar su respuesta? no está claro para mí – Sumod

7

Su código en realidad tiene dos problemas principales.

La primera es que no está llamando a el método upper, sino simplemente haciendo referencia a él. Necesitas llamarlo realmente (a través del Question.upper()) como lo hace w00t en su respuesta.

Poner algunas declaraciones de impresión de diagnóstico dentro de su bucle habría sido una buena manera de ver que (especialmente imprimir str(Question.upper)) (Tangente: Question es un mal nombre para una variable que contiene la respuesta a una pregunta del programa de pedido de la usuario)

En segundo lugar, la eliminación de elementos ya vistos de una lista que está iterando dará como resultado la omisión de valores. En realidad, no necesita copiar toda la lista para tratar con eso; basta con iterar al revés para solucionar el problema.

Por último, un par de puntos que son cosméticos menores raw_input() acepta un argumento rápida, por lo que no necesita una declaración de impresión independiente y llamando upper() en una cadena en sí será siempre devolver una cadena:

titles_list = ["English", "Math", "History", "IT", "Biology", "Spanish"] 
prompt = ("Do you want to keep the title: {}\n" 
      "or Delete it? Input Y for keep, N for Delete: ") 

for title in reversed(titles_list): 
    answer = raw_input(prompt.format(title)) 
    if answer.upper() == "N": 
     titles_list.remove(title) 

print titles_list 
+0

Es posible que desee mencionar que el nuevo formato de cadena de estilo solo funciona en python 2.7 y posterior. –

+0

En realidad está disponible en 2.6 o posterior – ncoghlan

+0

Pero sí, si necesita usar 2.5 o anterior, entonces el '{}' en la cadena de formato debe reemplazarse con un '% s' y el comando de formateo se convierte en' prompt% título'. – ncoghlan

1

Creo que el problema principal en su código era el uso incorrecto de la función superior. Una vez que lo solucione, puede eliminar los títulos de la lista como lo desee. Puede usar el índice o el valor. Aquí está el código recortado que funcionó para mí

 
#!/usr/bin/python 

import string 

titles_list = ["English", "Math", "Biology", "IT", "History"] 
for title in titles_list: 
    answer = raw_input("Do you want to keep this title %s, type y or n\n" % (title)) 
    if string.upper(answer) == "N": 
    # i = titles_list.index(title) 
    # del titles_list[i] 
    titles_list.remove(title) 
    print "now list is" , titles_list 
print titles_list 

Consulte las líneas comentadas usando el índice. Además, puede hacer que su código sea más conciso utilizando la función raw_input (prompt).

También debe pensar en el escenario donde hay varias ocurrencias de los mismos títulos en su lista, en ese caso sugiero obtener todos los índices para el título hasta que la lista esté vacía y eliminar los títulos usando del (índice) ya que las soluciones presentadas anteriormente eliminarán solo la primera aparición del título.

+0

No es necesario utilizar el módulo 'string' -' answer.upper() 'funciona bien. Sin embargo, ¿realmente probaste esto y ves qué pasa cuando presionas 'n' cada vez? No se te ofrecerá la posibilidad de eliminar '' Math '' o ''IT' 'de la lista. – ncoghlan

0

Sé que ya hay una respuesta, aquí hay otra forma de completar y demostrar la comprensión de la lista.

Este método toma una lista, pide guardar cada elemento y devuelve una nueva lista de exclusión de los marcados para su eliminación:

def delete_items(titles): 
    deleted_items = [] 
    for title in titles: 
     print('keep %s?' % title) 
     if str(raw_input().upper()) == 'N': 
      deleted_items.append(title) 
    return [e for e in titles if e not in deleted_items] 
Cuestiones relacionadas