生成器表达式与首先构造列表然后使用列表转换的生成器之间的行为不同

时间:2018-11-14 19:43:31

标签: python generator

这两段代码能否为下游应用程序产生不同的行为?换句话说,返回的对象是否有所不同?

 return (func(i) for i in a_list) 

 b_list=[] 
 for i in a_list:
     b_list.append(func(i))
 return (i for i in b_list)

PS:构建生成器的第二种方法非常有问题。

1 个答案:

答案 0 :(得分:1)

首先,此代码:

b_list=[] 
for i in a_list:
    b_list.append(func(i))
return (i for i in b_list)

与以下代码完全相同:

return iter([func(i) for i in a_list])

这些与这个之间的区别:

return (func(i) for i in a_list)

是因为后者是lazy,而另外两个是 eager -也就是说,后者每次调用其func方法时都会运行__next__(),而另一个两个会立即为func的每个项目运行a_list

因此,答案取决于func是否为pure function-在这种情况下,不管它何时运行且与外部/全局变量无关,它的行为是否相同。

这还取决于列表中的项目是否可变,是否通过其他代码更改列表本身。

如果答案分别为“是”和“否”,则除了内存占用空间外,答案都是相同的。

最后,只要我们在讨论功能概念,请考虑使用:

return map(func, a_list)

代替:

return (func(i) for i in a_list)

但是仅当您使用Python 3的可爱懒惰map()而不是Python 2的 evil 渴望map()时。