Python列表理解:使用“if”语句理解结果

时间:2017-11-21 03:23:36

标签: python list list-comprehension

您可以根据理解中转换的结果来过滤列表理解吗?

例如,假设您要删除列表中的每个字符串,并删除只是空格的字符串。我可以轻松地做到以下几点:

[x.strip() for x in str_list if x.strip()]

但是两次迭代列表。或者,您可以执行以下操作:

strip

但该实现执行for x in str_list: x = x.strip() if x: yield x 两次。我也可以使用发电机:

onCreateViewHolder

但现在这是一堆代码行。有没有办法做上述(1)只迭代一次; (2)只进行一次转换; (3)在单一列表中理解?上面的例子是一个玩具示例,但我想用更长的列表和非平凡的变换来做到这一点。

更新:我正在使用Python 2.7.X,并且更喜欢这方面的答案,但如果Python 3有一些新功能可以让它变得简单,我很乐意将它们理解为好。

2 个答案:

答案 0 :(得分:5)

不要将列表传递给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循环。

答案 1 :(得分:1)

为什么不嵌套理解?

result = (x for x in (y.strip() for y in str_list) if len(x))

内部()生成一个生成器,它只是str_list中字符串的剥离版本。外部()生成第二个生成器,它使用第一个生成器并仅生成非空元素。您只遍历列表一次,并且只将每个字符串剥离一次。