Cómo eliminar un elemento específico de una matriz usando python

138

Quiero escribir algo que elimine un elemento específico de una matriz. Sé que tengo que forrecorrer la matriz para encontrar el elemento que coincida con el contenido.

Digamos que tengo una variedad de correos electrónicos y quiero deshacerme del elemento que coincide con alguna cadena de correo electrónico.

En realidad, me gustaría usar la estructura de bucle for porque también necesito usar el mismo índice para otras matrices.

Aquí está el código que tengo:

for index, item in emails:
    if emails[index] == '[email protected]':
         emails.pop(index)
         otherarray.pop(index)
locoboy
fuente
66
¿Está buscando list.remove(x)?
Jacob
no exactamente.
Me
44
No debe cambiar la lista mientras itera sobre ella.
Jacob
¿Por qué no debería hacer esto? Tampoco me funciona.
locoboy
55
Tenga en cuenta esto: No modificarás una lista durante la iteración
Jacob

Respuestas:

200

No necesita iterar la matriz. Sólo:

>>> x = ['[email protected]', '[email protected]']
>>> x
['[email protected]', '[email protected]']
>>> x.remove('[email protected]')
>>> x
['[email protected]']

Esto eliminará la primera ocurrencia que coincida con la cadena.

EDITAR: después de su edición, aún no necesita repetir. Solo haz:

index = initial_list.index(item1)
del initial_list[index]
del other_list[index]
Bogdan
fuente
1
veo arriba me gustaría utilizar el bucle para reutilizar el mismo índice
locoboy
Edité mi respuesta. Todavía no hay necesidad de bucle.
Bogdan
1
¿Cómo comprueba primero que el elemento existe en initial_list? Podría haber un caso en el que no exista y no tenga que eliminarlo.
locoboy
17

Usar filter()y lambdaproporcionaría un método claro y conciso para eliminar valores no deseados:

newEmails = list(filter(lambda x : x != '[email protected]', emails))

Esto no modifica los correos electrónicos. Crea la nueva lista newEmails que contiene solo elementos para los que la función anónima devolvió True.

Ron Kalian
fuente
5

Su bucle for no es correcto, si necesita el índice en el uso del bucle for:

for index, item in enumerate(emails):
    # whatever (but you can't remove element while iterating)

En su caso, la solución de Bogdan está bien, pero su elección de estructura de datos no es tan buena. Tener que mantener estas dos listas con datos de uno relacionado con datos del otro en el mismo índice es torpe.

Una lista de tupple (correo electrónico, otros datos) puede ser mejor, o un dict con correo electrónico como clave.

MatthieuW
fuente
4

La forma más sensata de hacerlo es usar zip()una Lista de comprensión / Expresión de generador:

filtered = (
    (email, other) 
        for email, other in zip(emails, other_list) 
            if email == '[email protected]')

new_emails, new_other_list = zip(*filtered)

Además, si no está utilizando array.array()o numpy.array(), lo más probable es que esté utilizando []o list(), lo que le proporciona listas, no matrices. No es lo mismo.

Pillmuncher
fuente
1
Nadie está seguro de cómo esto es "cuerdo" en comparación con la respuesta de @ Bogdan, que es mucho, mucho más limpia.
Jordan Lapp
Gracias por señalar que las matrices no son lo mismo que las listas. La respuesta seleccionada no funciona en matrices en 2.7.
EL_DON
2

Hay una solución alternativa a este problema que también trata con coincidencias duplicadas.

Comenzamos con 2 listas de igual longitud: emails, otherarray. El objetivo es eliminar elementos de ambas listas para cada índice idonde emails[i] == '[email protected]'.

Esto se puede lograr utilizando una lista de comprensión y luego dividiendo a través de zip:

emails = ['[email protected]', '[email protected]', '[email protected]']
otherarray = ['some', 'other', 'details']

from operator import itemgetter

res = [(i, j) for i, j in zip(emails, otherarray) if i!= '[email protected]']
emails, otherarray = map(list, map(itemgetter(0, 1), zip(*res)))

print(emails)      # ['[email protected]', '[email protected]']
print(otherarray)  # ['some', 'details']
jpp
fuente