input = "foo ,,bar ,baz,"
tags = [x.strip() for x in input.split(',') if len(x.strip()) > 0]
所需的输出显然是一个没有空字符串的列表。
问题是本着微优化的精神;有没有办法不让strip()
候选人x
两次,即一次用于测试,一次用于附加?
换句话说,您能否在表达式中生成一个值,该值可以附加到列表中而无需执行两次工作?
input = "foo ,,bar ,baz,"
tags = [x.strip() for x in input.split(',') if len(x.strip()) > 0]
所需的输出显然是一个没有空字符串的列表。
问题是本着微优化的精神;有没有办法不让strip()
候选人x
两次,即一次用于测试,一次用于附加?
换句话说,您能否在表达式中生成一个值,该值可以附加到列表中而无需执行两次工作?
创建一个新字符串总是比扫描它更昂贵。x.isspace()
遇到第一个非空格字符后将返回
tags = [x.strip() for x in input.split(',') if x and not x.isspace()]
text = 'foo ,,bar ,baz,'
(我使用text
而不是input
asinput
是内置的名称。避免遮蔽内置。)
首先,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
如您所见,第一个是最快的。
这也有效...
text = "foo ,,bar ,baz,"
text.replace(',',' ').split()