python - terminar - ¿Cómo modificar las entradas de la lista durante el ciclo for?
for en python 3 (7)
Como el siguiente ciclo solo modifica los elementos ya vistos, se consideraría aceptable:
a = [''a'','' b'', ''c '', '' d '']
for i, s in enumerate(a):
a[i] = s.strip()
print(a) # -> [''a'', ''b'', ''c'', ''d'']
Que es diferente de:
a[:] = [s.strip() for s in a]
en que no requiere la creación de una lista temporal y una asignación de la misma para reemplazar el original, aunque sí requiere más operaciones de indexación.
Precaución: aunque puede modificar las entradas de esta manera, no puede cambiar el número de elementos en la list
sin arriesgarse a tener problemas.
Aquí hay un ejemplo de lo que quiero decir: eliminar una entrada desordena la indexación a partir de ese momento:
b = [''a'', '' b'', ''c '', '' d '']
for i, s in enumerate(b):
if s.strip() != b[i]: # leading or trailing whitespace?
del b[i]
print(b) # -> [''a'', ''c '']
(El resultado es incorrecto porque no eliminó todos los elementos que debería tener).
Ahora sé que no es seguro modificar la lista durante un bucle iterativo. Sin embargo, supongamos que tengo una lista de cadenas, y quiero quitar las cuerdas. ¿El reemplazo de valores mutables cuenta como modificación?
De su pregunta no queda claro cuál es el criterio para decidir qué cadenas eliminar, pero si tiene o puede hacer una lista de las cadenas que desea eliminar, podría hacer lo siguiente:
my_strings = [''a'',''b'',''c'',''d'',''e'']
undesirable_strings = [''b'',''d'']
for undesirable_string in undesirable_strings:
for i in range(my_strings.count(undesirable_string)):
my_strings.remove(undesirable_string)
que cambia my_strings a [''a'', ''c'', ''e'']
La modificación de cada elemento mientras se itera una lista está bien, siempre y cuando no cambie agregar o quitar elementos a la lista.
Puedes usar la comprensión de la lista:
l = [''a'', '' list'', ''of '', '' string '']
l = [item.strip() for item in l]
o simplemente haz el C-style
for loop:
for index, item in enumerate(l):
l[index] = item.strip()
No, no modificarías el "contenido" de la lista, si pudieras mutar las cadenas de esa manera. Pero en Python no son mutables. Cualquier operación de cadena devuelve una nueva cadena.
Si tenía una lista de objetos que sabía que podían modificarse, podría hacerlo siempre que no cambie el contenido real de la lista.
Por lo tanto, necesitarás hacer un mapa de algún tipo. Si usa una expresión de generador, [la operación] se realizará a medida que itere y ahorrará memoria.
Puedes hacer algo como esto:
a = [1,2,3,4,5]
b = [i**2 for i in a]
Se llama comprensión de la lista, para que le resulte más fácil ingresar dentro de una lista.
Se considera de forma pobre. Use una lista de comprensión en su lugar, con la asignación de división si necesita retener las referencias existentes a la lista.
a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print b
Una más para la variante de ciclo, me parece más limpia que una con enumerate ():
for idx in range(len(list)):
list[idx]=... # set a new value
# some other code which doesn''t let you use a list comprehension