¿Es posible eliminar varios elementos de una lista al mismo tiempo? Si quiero eliminar elementos en el índice 0 y 2, e intentar algo como del somelist[0]
, seguido de del somelist[2]
, la segunda declaración se eliminará realmente somelist[3]
.
Supongo que siempre podría eliminar primero los elementos con un número más alto, pero espero que haya una mejor manera.
somelist = [ lst[i] for i in xrange(len(lst)) if i not in set(indices) ]
?Por alguna razón, no me gusta ninguna de las respuestas aquí. Sí, funcionan, pero estrictamente hablando, la mayoría de ellos no están eliminando elementos de una lista, ¿verdad? (Pero haciendo una copia y luego reemplazando la original con la copia editada).
¿Por qué no simplemente eliminar primero el índice más alto?
¿Hay alguna razón para esto? Yo solo haría:
Si realmente no desea eliminar elementos al revés, entonces supongo que debería reducir los valores de los índices que son mayores que el último índice eliminado (realmente no puede usar el mismo índice ya que tiene una lista diferente) o usar una copia de la lista (que no estaría 'borrando' sino reemplazando el original con una copia editada).
¿Me falta algo aquí, alguna razón para NO eliminar en el orden inverso?
fuente
Si está eliminando varios elementos no adyacentes, entonces lo que describe es la mejor manera (y sí, asegúrese de comenzar desde el índice más alto).
Si sus elementos son adyacentes, puede usar la sintaxis de asignación de divisiones:
fuente
del a[2:10]
con el mismo efecto.Puedes usar
numpy.delete
lo siguiente:Si no le importa terminar con una
numpy
matriz al final, puede omitir el.tolist()
. También debería ver algunas mejoras de velocidad bastante importantes, lo que hace que esta sea una solución más escalable. No lo he comparado, pero lasnumpy
operaciones son código compilado escrito en C o Fortran.fuente
Como especialización de la respuesta de Greg, incluso puede usar la sintaxis de corte extendida. p.ej. Si desea eliminar los elementos 0 y 2:
Esto no cubre ninguna selección arbitraria, por supuesto, pero ciertamente puede funcionar para eliminar dos elementos.
fuente
Como una función:
Se ejecuta en n log (n) tiempo, lo que debería convertirlo en la solución correcta más rápida hasta el momento.
fuente
n log n
? De Verdad? No creo quedel list[index]
sea O (1).Entonces, ¿esencialmente quieres eliminar varios elementos en una sola pasada? En ese caso, la posición del siguiente elemento a eliminar se compensará con la cantidad que se haya eliminado anteriormente.
Nuestro objetivo es eliminar todas las vocales, que se calculan previamente como índices 1, 4 y 7. Tenga en cuenta que es importante que los índices to_delete estén en orden ascendente, de lo contrario no funcionará.
Sería más complicado si quisieras eliminar los elementos en cualquier orden. En mi opinión, la clasificación
to_delete
podría ser más fácil que averiguar cuándo debería o no restarindex
.fuente
Soy un principiante total en Python, y mi programación en este momento es cruda y sucia, por decir lo menos, pero mi solución fue usar una combinación de los comandos básicos que aprendí en los primeros tutoriales:
Obviamente, debido a que tiene que elegir un carácter de "marca para eliminación", esto tiene sus limitaciones.
En cuanto al rendimiento ya que el tamaño de la lista se escala, estoy seguro de que mi solución es subóptima. Sin embargo, es sencillo, lo que espero atraiga a otros principiantes, y funcionará en casos simples en los que
some_list
sea de un formato conocido, por ejemplo, siempre numérico ...fuente
Aquí hay una alternativa, que no utiliza enumerate () para crear tuplas (como en la respuesta original de SilentGhost).
Esto me parece más legible. (Tal vez me sentiría diferente si tuviera la costumbre de usar enumerar). CAVEAT: No he probado el rendimiento de los dos enfoques.
NOTA: sintaxis de Python 2.7. Para Python 3,
xrange
=>range
.Uso:
somelista
--- BONIFICACIÓN ---
Eliminar múltiples valores de una lista. Es decir, tenemos los valores que queremos eliminar:
Uso:
somelista
Esta es la misma respuesta que antes, pero esta vez proporcionamos los VALORES que se eliminarán
[0, 44, 55]
.fuente
[ value for (i, value) in enumerate(lst) if i not in set(indices) ]
. Pero dejaré mi respuesta aquí, porque también muestro cómo eliminar por valores. Es un caso más fácil, pero podría ayudar a alguien.indices_as_set = set(indices)
,[ value for (i, value) in enumerate(lst) if i not in indices_as_set ]
, para acelerarlo.delete__by_values()
?Un método alternativo de comprensión de listas que utiliza valores de índice de listas:
Esto devuelve:
fuente
index
es engañoso ya que en el iterador de la lista se usa el métodoindex()
Aquí hay otro método que elimina los elementos en su lugar. Además, si su lista es realmente larga, es más rápida.
fuente
Esto se ha mencionado, pero de alguna manera nadie logró hacerlo bien.
En
O(n)
solución sería:Esto está muy cerca de la versión de SilentGhost , pero agrega dos llaves.
fuente
O(n)
ocurre si cuenta las búsquedas que se realizanlog(len(indices))
para cada iteración.j not in indices
esO(1)
.j not in indices
aún requiere búsqueda, que esO(log(len(indices)))
. Si bien estoy de acuerdo en que una búsqueda en un conjunto de 2 elementos califica comoO(1)
, en el caso general lo seráO(log(N))
. De cualquier maneraO(N log(N))
todavía lateO(N^2)
.j not in indices
esO(1)
, en serio.Básicamente es lo mismo que la respuesta más votada, solo una forma diferente de escribirla. Tenga en cuenta que usar l.index () no es una buena idea, ya que no puede manejar elementos duplicados en una lista.
fuente
El método de eliminación provocará muchos cambios en los elementos de la lista. Creo que es mejor hacer una copia:
fuente
técnicamente, la respuesta es NO, no es posible eliminar dos objetos AL MISMO TIEMPO. Sin embargo, ES posible eliminar dos objetos en una línea de Python hermosa.
borrará recusivamente
foo['bar']
, luegofoo['baz']
fuente
podemos hacer esto mediante el uso de un ciclo for iterando sobre los índices después de ordenar la lista de índices en orden descendente
fuente
Para los índices 0 y 2 de la lista A:
Para algunos índices aleatorios para eliminar de la lista A:
fuente
Quería una forma de comparar las diferentes soluciones que facilitaban girar los mandos.
Primero generé mis datos:
Luego definí mis funciones:
Luego solía
timeit
comparar las soluciones:Salida
Entonces el generador con los índices en a
set
fue el ganador. Ydel
es un poco más rápido entoncespop
.fuente
Puedes usar esta lógica:
fuente
Otra implementación de la idea de eliminar del índice más alto.
fuente
De hecho, puedo pensar en dos formas de hacerlo:
cortar la lista como (esto elimina los elementos primero, tercero y octavo)
somelist = somelist [1: 2] + somelist [3: 7] + somelist [8:]
hacer eso en su lugar, pero uno a la vez:
somelist.pop (2) somelist.pop (0)
fuente
Puedes hacerlo así en un dict, no en una lista. En una lista los elementos están en secuencia. En un dict dependen solo del índice.
Código simple solo para explicarlo haciendo :
Una forma de "convertir" una lista en un dict es:
El inverso es:
De todos modos, creo que es mejor comenzar a eliminar del índice más alto como dijiste.
fuente
Para generalizar el comentario de @sth . La eliminación de elementos en cualquier clase, que implementa abc.MutableSequence , y
list
en particular, se realiza mediante un__delitem__
método mágico. Este método funciona de manera similar__getitem__
, lo que significa que puede aceptar un número entero o un segmento. Aquí hay un ejemplo:Esto dará salida
fuente
Importarlo solo por esta razón puede ser exagerado, pero si de
pandas
todos modos lo está utilizando , entonces la solución es simple y directa:fuente
Evita el costo de clasificación y tener que copiar explícitamente la lista.
fuente
¿Qué tal uno de estos (soy muy nuevo en Python, pero parecen estar bien):
['Atlántico', 'Pacífico', 'Indio']
['Atlántico', 'Pacífico', 'Indio']
fuente
Ninguna de las respuestas ofrecidas hasta ahora realiza la eliminación en su lugar en O (n) en la longitud de la lista para eliminar un número arbitrario de índices, así que aquí está mi versión:
fuente
Puedes usar remove, también.
fuente
Lo puse todo junto en una
list_diff
función que simplemente toma dos listas como entradas y devuelve su diferencia, conservando el orden original de la primera lista.Uso de la muestra:
fuente