1)近乎英式风格:
使用in操作符测试是否存在,然后应用删除方法。
if thing in some_list: some_list.remove(thing)
removemethod将只删除thing的第一次出现,以便删除所有可以使用while而不是if的出现。
while thing in some_list: some_list.remove(thing)
很简单,可能是我的选择。对于小列表(无法抗拒一行程序)
2)鸭型,EAFP风格:
这种先开枪,后提问的态度在Python中很常见。不需要提前测试对象是否合适,只需执行操作并捕获相关异常:
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!")
当然,上面例子中的第二个except子句不仅幽默有问题,而且完全没有必要(重点是为不熟悉这个概念的人演示duck typing)。
如果你期望事物多次出现:
while True:
try:
some_list.remove(thing)
except ValueError:
break
对于这个特定的用例来说有点啰嗦,但在Python中非常习惯。
它的性能比#1要好
PEP 463为try/提出了一个更短的语法,除了简单的用法之外,这在这里很方便,但它没有被批准。
然而,使用contextlib的suppress() contextmanager(在python 3.4中引入),上面的代码可以简化为:
with suppress(ValueError, AttributeError):
some_list.remove(thing)
同样地,如果你期望事物多次出现:
with suppress(ValueError):
while True:
some_list.remove(thing)
3)功能风格:
大约在1993年,Python得到了lambda、reduce()、filter()和map(),多亏了一个Lisp黑客,他错过了这些,并提交了工作补丁*。您可以使用过滤器从列表中删除元素:
is_not_thing = lambda x: x is not thing
cleaned_list = filter(is_not_thing, some_list)
有一个快捷方式可能对你的情况有用:如果你想过滤空项(实际上是bool(item) == False的项,比如None, 0,空字符串或其他空集合),你可以将None作为第一个参数:
cleaned_list = filter(None, some_list)
[update]: in Python 2.x, filter(function, iterable) used to be equivalent to [item for item in iterable if function(item)] (or [item for item in iterable if item] if the first argument is None); in Python 3.x, it is now equivalent to (item for item in iterable if function(item)). The subtle difference is that filter used to return a list, now it works like a generator expression - this is OK if you are only iterating over the cleaned list and discarding it, but if you really need a list, you have to enclose the filter() call with the list() constructor.
*These Lispy flavored constructs are considered a little alien in Python. Around 2005, Guido was even talking about dropping filter - along with companions map and reduce (they are not gone yet but reduce was moved into the functools module, which is worth a look if you like high order functions).
4)数学风格:
列表推导式自从PEP 202在2.0版中引入以来,就成为Python中列表操作的首选样式。它背后的基本原理是,列表推导式提供了一种更简洁的方式来创建列表,在目前将使用map()和filter()和/或嵌套循环的情况下。
cleaned_list = [ x for x in some_list if x is not thing ]
PEP 289在2.4版中引入了生成器表达式。生成器表达式更适合于不需要(或不希望)在内存中创建完整列表的情况——例如,当您只想每次迭代一个元素时。如果你只是在列表上迭代,你可以把生成器表达式看作一个惰性求值列表理解:
for item in (x for x in some_list if x is not thing):
do_your_thing_with(item)
请参阅GvR的Python历史博客文章。
此语法受到数学中的集合构建器符号的启发。
Python 3也有set和dict推导式。
笔记
你可能想使用不等式运算符!=而不是is not(区别很重要)
对于包含列表副本的方法的批评者:与流行的观点相反,生成器表达式并不总是比列表推导更有效-在抱怨之前请先进行剖析