Python - 还有其他方法可以在列表推导中应用函数和过滤器吗?

时间:2014-02-03 21:57:05

标签: python list-comprehension

多年来,这一直困扰着我。

鉴于我有一个单词列表:

words = [ 'one', 'two', 'three', '', ' four', 'five ', 'six', \
         'seven', 'eight ', ' nine', 'ten', '']

即使它超级轻量级​​,我仍然觉得写这个列表理解很奇怪:

cleaned = [ i.strip() for i in words if i.strip() ]

我不喜欢两次应用strip()。它看起来很傻。

这样的速度略微/可忽略不计:

_words = [ w.strip() for w in words ]
cleaned = [ w for w in _words if w ]

也与

相同
cleaned = [ i for i in [ w.strip() for w in words ] if i ]

我想知道是否有其他方法可以写这个。

我对列表推导的嵌套循环形式很感兴趣(参见Idiom for flattening a shallow nested list: how does it work?),但我无法解决任何问题。

更新

我将基准测试放在github上,概述了我原来的3种方法,以及下面分享的方法。

最快的是@Martijn Pieters filter();将内部列表转换为生成器表达式对速度的影响可以忽略不计,但对于内存管理应该更好(根据python的文档)。

所涉及的所有速度差异预计可以忽略不计,不值得分享。

2 个答案:

答案 0 :(得分:11)

生成器表达式:

cleaned = [i for i in (word.strip() for word in words) if i]

使用filter()map()

cleaned = filter(None, map(str.strip, words))

后者在Python 3中生成一个生成器;将list()应用于map()或将cleaned = [i for i in map(str.strip, words) if i] 与列表理解相结合:

{{1}}

答案 1 :(得分:1)

我有一点变化,我创建了一个单值临时列表:

>>> cleaned = [stripped for word in words
...            for stripped in [word.strip()]
...            if stripped]

更一般地说:

>>> values = [transformed for value in sequence
              for transformed in [transform(value)]
              if want(transformed)]