Hice esta función que elimina todos los números impares de una lista. (No puedo modificar la lista original)

Código:-

def purify(sequence):
   purified = sequence
   for i in purified:
       if i % 2 != 0:
          purified.remove(i)
   return purified

La función funciona en la mayoría de la lista, pero si una lista tiene los mismos valores como [4, 5, 5, 4], devuelve [4, 5, 4].
He cambiado el código para lograr lo que necesitaba, pero tengo curiosidad por qué sucede esto.

-1
Lucifer 11 may. 2019 a las 06:09

4 respuestas

La mejor respuesta

purified = sequence no crea una copia de sequence y no se asigna a purified, sino que ambas variables apuntan al mismo objeto, que está intentando hacer. Además, también está modificando la misma lista en la que está iterando, de ahí el comportamiento extraño.

Tienes algunas opciones, y todas funcionan en Python 2.7

  • Haga una copia de la secuencia a través de sequence[:] llamada empalme de listas e itere en ella
def purify(sequence):

    #Iterate on copy of sequence
    for i in sequence[:]:
        if i % 2 != 0:
            sequence.remove(i)
    return sequence

print purify([4, 5, 5, 4])
#[4, 4]
  • Utilice la comprensión de la lista para elegir solo valores pares de la lista
def purify(sequence):

    #Pick only even values
    return [item for item in sequence if item%2 == 0]

print purify([4, 5, 5, 4])
#[4, 4]
  • Use filter para filtrar valores impares
def purify(sequence):
    # Iterate on copy of sequence
    return list(filter(lambda x:x%2==0, sequence))

print(purify([4, 5, 5, 4]))
# [4, 4]
2
Devesh Kumar Singh 11 may. 2019 a las 03:51

En python2.7 use el módulo copy.

Ej:

from copy import copy

def purify(sequence):
    purified = copy(sequence)
    for i in sequence:
        if i % 2 != 0:
            purified.remove(i)

    return purified
print purify([4, 5, 5, 4])
1
Rakesh 11 may. 2019 a las 03:32

No debe intentar eliminar elementos mientras itera. Además, purified = sequence en realidad no crea una copia de sequence. La mejor manera de hacer esto es usar una lista de comprensión como esta:

def purify(sequence):
    purified = [i for i in sequence if i % 2 == 0]
    return purified
2
iz_ 11 may. 2019 a las 03:17

(Podría haber jurado que respondí a un engañado de esto, pero no puedo encontrarlo ...)

De todos modos, la razón es que estás modificando una secuencia mientras iteras sobre ella. Deberías hacer algo como esto en su lugar:

# Python 3
def purify(sequence):
    purified = sequence.copy()
    for i in sequence:
        if i % 2 != 0:
            purified.remove(i)

    return purified

# Python 2
from copy import copy

def purify(sequence):
    purified = copy(sequence)
    for i in sequence:
        if i % 2 != 0:
            purified.remove(i)

    return purified

Alternativamente, puede comenzar con un list vacío y agregar elementos que satisfagan sus criterios:

def purify(sequence):
    purified = []
    for i in sequence:
        if i % 2 == 0:
            purified.append(i)

    return purified

O, con una comprensión list, esto:

purified = [i for i in sequence if i % 2 == 0]
1
gmds 11 may. 2019 a las 03:32