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] == 'something@something.com':
         emails.pop(index)
         otherarray.pop(index)

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

Respuestas:


200

No necesita iterar la matriz. Sólo:

>>> x = ['ala@ala.com', 'bala@bala.com']
>>> x
['ala@ala.com', 'bala@bala.com']
>>> x.remove('ala@ala.com')
>>> x
['bala@bala.com']

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]

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 != 'something@something.com', 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.


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.


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 == 'something@something.com')

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.


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] == 'something@something.com'.

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

emails = ['abc@def.com', 'something@something.com', 'ghi@jkl.com']
otherarray = ['some', 'other', 'details']

from operator import itemgetter

res = [(i, j) for i, j in zip(emails, otherarray) if i!= 'something@something.com']
emails, otherarray = map(list, map(itemgetter(0, 1), zip(*res)))

print(emails)      # ['abc@def.com', 'ghi@jkl.com']
print(otherarray)  # ['some', 'details']
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.