1) 几乎是英式风格:
使用in 运算符测试是否存在,然后应用remove 方法。
if thing in some_list: some_list.remove(thing)
remove方法将只删除第一次出现的thing,为了删除所有出现的你可以使用while而不是if。
while thing in some_list: some_list.remove(thing)
- 足够简单,可能是我的选择。对于小列表(无法抗拒单行)
这种先发后问的态度在 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 子句不仅是有问题的幽默,而且完全没有必要(重点是为了向不熟悉该概念的人说明鸭式打字)。
如果您预计事物会多次出现:
while True:
try:
some_list.remove(thing)
except ValueError:
break
- 对于这个特定的用例有点冗长,但在 Python 中非常惯用。
- 这比 #1 表现更好
-
PEP 463 提出了一种更短的 try/except 语法,在这里很方便,但没有被批准。
但是,使用contextlib's 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 黑客错过了它们并提交了工作补丁*。您可以使用filter 从列表中删除元素:
is_not_thing = lambda x: x is not thing
cleaned_list = filter(is_not_thing, some_list)
有一个快捷方式可能对您的情况有用:如果您想过滤掉空项目(实际上是 bool(item) == False 的项目,如 None、零、空字符串或其他空集合),您可以通过没有作为第一个参数:
cleaned_list = filter(None, some_list)
-
[更新]:在 Python 2.x 中,
filter(function, iterable) 曾经等价于[item for item in iterable if function(item)](如果第一个参数是None,则为[item for item in iterable if item]);在 Python 3.x 中,它现在等同于 (item for item in iterable if function(item))。细微的区别是过滤器用于返回一个列表,现在它像一个生成器表达式一样工作 - 如果您只是迭代清理过的列表并丢弃它,这是可以的,但是如果您真的需要一个列表,则必须将 @ 括起来987654365@ 使用 list() 构造函数调用。
- *这些 Lispy 风格的构造在 Python 中被认为有点陌生。大约在 2005 年,Guido was even talking about dropping
filter - 以及同伴map 和reduce(他们还没有消失,但reduce 被移入functools 模块,如果你喜欢high order functions,值得一看)。
4) 数学风格:
List comprehensions 自从PEP 202 在 2.0 版中引入以来,成为 Python 中列表操作的首选样式。其背后的基本原理是,列表推导式提供了一种更简洁的方式来在当前使用 map() 和 filter() 和/或嵌套循环的情况下创建列表。
cleaned_list = [ x for x in some_list if x is not thing ]
PEP 289 在 2.4 版中引入了生成器表达式。生成器表达式更适合您并不真正需要(或不希望)在内存中创建完整列表的情况 - 例如当您只想一次迭代一个元素时。如果您只是对列表进行迭代,则可以将生成器表达式视为lazy evaluated 列表推导:
for item in (x for x in some_list if x is not thing):
do_your_thing_with(item)
注意事项
- 您可能希望使用不等式运算符
!= 而不是is not (the difference is important)
- 对于暗示列表副本的方法的批评者:与流行的看法相反,生成器表达式并不总是比列表推导式更有效 - 请在抱怨之前先分析