你能根据理解转换的结果过滤列表理解吗?
例如,假设您要去除列表中的每个字符串,并删除只是空白的字符串。我可以轻松地执行以下操作:
filter(None, [x.strip() for x in str_list])
但这会遍历列表两次。或者,您可以执行以下操作:
[x.strip() for x in str_list if x.strip()]
但是该实现执行了两次 strip
。我还可以使用生成器:
for x in str_list:
x = x.strip()
if x:
yield x
但现在那是一堆代码行。有什么办法可以做到上述(1)只迭代一次; (2) 只进行一次转换;和(3)在一个列表理解中?上面的例子是一个玩具例子,但我想用更长的列表和重要的转换来做到这一点。
更新:我正在使用 Python 2.7.X,并且更喜欢其中的答案,但如果 Python 3 有一些新功能可以使这变得容易,我很乐意了解它们作为好吧。
最佳答案
不要将列表传递给filter
,传递一个生成器表达式,它只会被迭代一次:
filter(None, (x.strip() for x in str_list))
这与使用像这样的嵌套生成器完全相同
[y for y in (x.strip() for x in str_list) if y]
这两种情况都依赖于生成器的惰性评估:str_list
的每个元素都将在创建相应的输出元素时恰好被处理一次。不会制作中间列表。
理解方法非常适合像这样的小型一次性转换。在我看来,即使是这里在转换后进行过滤的简单示例,也在插入可读性的极限。对于任何重要的转换和过滤器序列,我建议使用 for
循环。
关于Python 列表理解 : Using "if" Statement on Result of the Comprehension,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47404659/