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

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

问题是本着微优化的精神;有没有办法不让strip()候选人x两次,即一次用于测试,一次用于附加?

换句话说,您能否在表达式中生成一个值,该值可以附加到列表中而无需执行两次工作?

4

3 回答 3

9

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

tags = [x.strip() for x in input.split(',') if x and not x.isspace()]
于 2012-05-23T23:00:15.643 回答
3
text = 'foo ,,bar ,baz,'

(我使用text而不是inputasinput是内置的名称。避免遮蔽内置。)

首先,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

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

于 2012-05-23T22:52:52.540 回答
1

这也有效...

 text = "foo ,,bar ,baz,"
 text.replace(',',' ').split()
于 2012-05-23T23:21:45.437 回答