1) Estilo casi inglés:
Pruebe la presencia utilizando el in
operador, luego aplique el remove
método.
if thing in some_list: some_list.remove(thing)
El remove
método eliminará solo la primera aparición de thing
, para eliminar todas las ocurrencias que puede usar en while
lugar de if
.
while thing in some_list: some_list.remove(thing)
- Bastante simple, probablemente sea mi elección. Para listas pequeñas (no puedo resistir una sola línea)
Esta actitud de disparar primero-preguntar-hacer-última es común en Python. En lugar de probar por adelantado si el objeto es adecuado, simplemente realice la operación y capture las excepciones relevantes:
try:
some_list.remove(thing)
except ValueError:
pass # or scream: thing not in some_list!
except AttributeError:
call_security("some_list not quacking like a list!")
Por supuesto, la segunda cláusula, excepto en el ejemplo anterior, no es solo de humor cuestionable sino totalmente innecesaria (el punto era ilustrar la escritura de pato para personas que no están familiarizadas con el concepto).
Si espera múltiples ocurrencias de cosas:
while True:
try:
some_list.remove(thing)
except ValueError:
break
- un poco detallado para este caso de uso específico, pero muy idiomático en Python.
- esto funciona mejor que el n. ° 1
- PEP 463 propuso una sintaxis más corta para probar / excepto el uso simple que sería útil aquí, pero no fue aprobada.
Sin embargo, con contextmanager suppress () contextmanager (introducido en python 3.4) el código anterior se puede simplificar a esto:
with suppress(ValueError, AttributeError):
some_list.remove(thing)
Nuevamente, si espera múltiples ocurrencias de cosas:
with suppress(ValueError):
while True:
some_list.remove(thing)
3) estilo funcional:
Alrededor de 1993, consiguió Python lambda
, reduce()
, filter()
y map()
, gracias a la Lisp hacker que los echaba de menos y presentados parches de trabajo *. Puede usar filter
para eliminar elementos de la lista:
is_not_thing = lambda x: x is not thing
cleaned_list = filter(is_not_thing, some_list)
Hay un acceso directo que puede ser útil para su caso: si desea filtrar elementos vacíos (de hecho, elementos bool(item) == False
como None
cero, cadenas vacías u otras colecciones vacías), puede pasar Ninguno como primer argumento:
cleaned_list = filter(None, some_list)
- [actualización] : en Python 2.x,
filter(function, iterable)
solía ser equivalente a [item for item in iterable if function(item)]
(o [item for item in iterable if item]
si el primer argumento es None
); en Python 3.x, ahora es equivalente a (item for item in iterable if function(item))
. La sutil diferencia es que el filtro utilizado para devolver una lista, ahora funciona como una expresión generadora: esto está bien si solo está iterando sobre la lista limpia y descartándola, pero si realmente necesita una lista, debe encerrar la filter()
llamada con el list()
constructor
- * Estas construcciones con sabor a Lispy se consideran un poco extraterrestres en Python. Alrededor de 2005, Guido incluso estaba hablando de dejar caer
filter
, junto con compañeros map
y reduce
(aún no se han ido, pero reduce
se trasladó al módulo functools , que vale la pena ver si le gustan las funciones de alto orden ).
4) Estilo matemático:
La comprensión de listas se convirtió en el estilo preferido para la manipulación de listas en Python desde que se introdujo en la versión 2.0 de PEP 202 . La razón detrás de esto es que las listas por comprensión proporcionan una forma más concisa para crear listas en situaciones en las que map()
y filter()
serían utilizadas actualmente y / o bucles anidados.
cleaned_list = [ x for x in some_list if x is not thing ]
Las expresiones generadoras fueron introducidas en la versión 2.4 por PEP 289 . Una expresión generadora es mejor para situaciones en las que realmente no necesita (o desea) tener una lista completa creada en la memoria, como cuando solo desea iterar sobre los elementos uno por uno. Si solo está iterando sobre la lista, puede pensar en una expresión generadora como una comprensión perezosa de la lista evaluada :
for item in (x for x in some_list if x is not thing):
do_your_thing_with(item)
Notas
- es posible que desee utilizar el operador de desigualdad en
!=
lugar de is not
( la diferencia es importante )
- Para los críticos de los métodos que implican una copia de la lista: contrariamente a la creencia popular, las expresiones generadoras no siempre son más eficientes que las comprensiones de listas.