这个Python列表理解表达式可以简化吗?

时间:2012-05-23 22:49:42

标签: python list-comprehension

input = "foo ,,bar ,baz,"
tags = [x.strip() for x in input.split(',') if len(x.strip()) > 0] 

所需的输出显然是一个没有空字符串的列表。

问题在于微观优化的精神;有没有办法strip()候选人x两次,即一次为测试,一次为追加?

要改写,您是否可以在表达式中生成一个值,该表达式可以在不进行两次工作的情况下附加到列表中?

3 个答案:

答案 0 :(得分:9)

创建新字符串总是比扫描它更昂贵。遇到第一个非空格字符后,x.isspace()将返回

tags = [x.strip() for x in input.split(',') if x and not x.isspace()]

答案 1 :(得分:3)

text = 'foo ,,bar ,baz,'

(我使用text而不是input,因为input是内置的名称。避免遮蔽内置组件。)

首先,len(x.strip()) > 0可以简单地(并且更有效地)编写为x.strip()

tags = [x.strip() for x in text.split(',') if x.strip()]

如果你真的想,你可以只做一次,但我不确定它是否会更快:

tags = [x for x in (x.strip() for x in text.split(',')) if x]

如果你真的想,你甚至可以在功能上做到......

tags = filter(bool, map(lambda x: x.strip(), text.split(',')))

表现数据:

>>> from timeit import timeit
>>> timeit(lambda: [x.strip() for x in text.split(',') if x.strip()])
1.9443869590759277
>>> timeit(lambda: [x for x in (x.strip() for x in text.split(',')) if x])
2.1135239601135254
>>> timeit(lambda: filter(bool, map(lambda x: x.strip(), text.split(','))))
2.52907395362854

如你所见,第一个是最快的。

答案 2 :(得分:1)

这也有效......

 text = "foo ,,bar ,baz,"
 text.replace(',',' ').split()