2012-06-07 6 views
5

que tiene una lista de caracteres y la lista de índicesforma concisa para eliminar elementos de la lista por el índice en Python

myList = ['a','b','c','d'] 
toRemove = [0,2] 

y que me gustaría conseguir esto en una sola operación

myList = ['b','d'] 

I podría hacer esto, pero ¿hay alguna forma de hacerlo más rápido?

toRemove.reverse() 
for i in toRemove: 
    myList.pop(i) 
+1

La implementación de ejemplo que proporciona es incorrecta, o tal vez su especificación. Ese algoritmo elimina el elemento en el índice 0, luego elimina el elemento que se movió al índice 2 debido a la eliminación (es decir, ''d''). – delnan

+0

Usé 'toRemove.reverse' para que el primer elemento que se elimine esté en el índice 2 y luego elimino el elemento en el índice 0. Esto solo funciona cuando la lista' toRemove' está ordenada. – Youcha

Respuesta

4

Si lo desea, puede usar numpy.

import numpy as np 

myList = ['a','b','c','d'] 
toRemove = [0,2] 

new_list = np.delete(myList, toRemove) 

Resultado:

>>> new_list 
array(['b', 'd'], 
     dtype='|S1') 

Tenga en cuenta que es una new_listnumpyarray.

+2

¿No crees que Numpy es un poco exagerado solo por un simple problema de 'eliminar matriz'? –

+1

Tal vez el OP ya está usando 'numpy' y las listas en cuestión son millones de elementos? Si es así, probablemente sea la respuesta más rápida. –

+0

@SuperDisk, creo que la forma 'numpy' es muy conveniente, y podría ser útil.Por supuesto, esta tarea es fácil sin 'numpy', pero vale la pena mencionar la opción 'numpy'. – Akavall

5

RESPUESTA GENERAL

>>> myList = ['a','b','c','d'] 
>>> toRemove = [0,2] 
>>> 
>>> [v for i, v in enumerate(myList) if i not in toRemove] 
['b', 'd'] 
>>> 
+2

Haz 'toRemove' un conjunto y este es realmente un algoritmo muy bueno. Es 'O (m)' en lugar de 'O (n * m)' donde 'n = len (toRemove); m = len (myList) 'ya que no copia repetidamente la mitad de la matriz cada vez que elimina un elemento. – delnan

+0

Hacer 'toRemove' un' set' es probablemente una buena idea, pero depende de cuánto tiempo 'toRemove' y' myList' determine si será una mejora. ¡No lo escribí originalmente ya que iba por conciso! –

1

de una sola línea:

>>>[myList[x] for x in range(len(myList)) if not x in [0,2]] 
['b', 'd'] 
0

Se puede escribir una función que lo haga por usted.

def removethese(list, *args): 
    for arg in args: 
     del list[arg] 

A continuación, realice

mylist = ['a', 'b', 'c', 'd', 'e'] 
removethese(mylist, 0, 1, 4) 

milista ahora es [ 'c', 'd']

+0

Esta implementación es tan incorrecta como OP (suponiendo, de nuevo, que la especificación es correcta). – delnan

5

Se podría utilizar una lista por comprensión como han sugerido otras respuestas, pero para que sea realmente más rápido Sugeriría usar un set para el conjunto de índices que desea eliminar.

>>> myList = ['a','b','c','d'] 
>>> toRemove = set([0,2]) 
>>> [x for i,x in enumerate(myList) if i not in toRemove] 
['b', 'd'] 

Comprobación de cada elemento en myList contra cada elemento en toremove es O (n * m) (donde n es la longitud de myList y m es la longitud de toremove). Si utiliza un set, la comprobación de membresía es O (1), por lo que todo el procedimiento se convierte en O (n). Sin embargo, tenga en cuenta que la diferencia de velocidad no se notará a menos que quitar sea realmente grande (digamos más de mil).

Cuestiones relacionadas