如果存在,如何删除列表中的项目?
我正在new_tag
从表单文本字段self.response.get("new_tag")
,并selected_tags
从复选框中的字段
self.response.get_all("selected_tags")
我将它们像这样组合:
tag_string = new_tag
new_tag_list = f1.striplist(tag_string.split(",") + selected_tags)
(f1.striplist
此函数在列表中的字符串内去除空格。)
但在这种情况下tag_list
是空的(没有新的标签进入),但也有一些selected_tags
,new_tag_list
包含一个空字符串"
"
。
例如,来自logging.info
:
new_tag
selected_tags[u'Hello', u'Cool', u'Glam']
new_tag_list[u'', u'Hello', u'Cool', u'Glam']
我如何摆脱空字符串?
如果列表中有一个空字符串:
>>> s = [u'', u'Hello', u'Cool', u'Glam']
>>> i = s.index("")
>>> del s[i]
>>> s
[u'Hello', u'Cool', u'Glam']
但是,如果没有空字符串:
>>> s = [u'Hello', u'Cool', u'Glam']
>>> if s.index(""):
i = s.index("")
del s[i]
else:
print "new_tag_list has no empty string"
但这给出了:
Traceback (most recent call last):
File "<pyshell#30>", line 1, in <module>
if new_tag_list.index(""):
ValueError: list.index(x): x not in list
为什么会发生这种情况,我该如何解决?
-
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)
- 足够简单,可能是我的选择。对于小清单(无法抗拒一线)
2)[鸭类型的](http://docs.python.org/glossary.html#term-duck-
typing),EAFP风格:
这种先问后问的态度在Python中很常见。无需预先测试对象是否合适,只需执行操作并捕获相关的Exception:
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的prevent()contextmanager(在python
3.4中引入),可以将上述代码简化为:with suppress(ValueError, AttributeError): some_list.remove(thing)
同样,如果您希望事物发生多次:
with suppress(ValueError): while True: some_list.remove(thing)
3)功能风格:
1993年左右,巨蟒有
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
零,空字符串或其他空集合等项目),则可以将None作为第一个参数传递:cleaned_list = filter(None, some_list)
- [update] :在Python 2.x中,
filter(function, iterable)
曾经等价于[item for item in iterable if function(item)]
(或[item for item in iterable if item]
第一个参数为None
);在Python 3.x中,它现在等效于(item for item in iterable if function(item))
。细微的差别是过滤器用于返回列表,现在它就像生成器表达式一样工作-如果仅遍历清理后的列表并将其丢弃,则可以,但是如果您确实需要列表,则必须将filter()
调用括起来与list()
构造函数。 - *这些Lispy风格的构造在Python中被认为有点陌生。2005年左右,圭多甚至被谈论下降
filter
-与同伴一起map
和reduce
(他们还没有消失,但reduce
被转移到functools模块,这是值得一试,如果你喜欢高阶函数)。
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还设置并决定了理解能力。
笔记
- 您可能要使用不等式运算符
!=
来代替is not
(区别很重要) - 对于暗示要使用列表副本的方法的批评者:与流行的看法相反,生成器表达式并不总是比列表理解更有效-请在抱怨之前进行剖析