您可以根据理解中转换的结果来过滤列表理解吗?
例如,假设您要删除列表中的每个字符串,并删除只是空格的字符串。我可以轻松地做到以下几点:
[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有一些新功能可以让它变得简单,我很乐意将它们理解为好。
答案 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
中字符串的剥离版本。外部()
生成第二个生成器,它使用第一个生成器并仅生成非空元素。您只遍历列表一次,并且只将每个字符串剥离一次。