循环内的副作用会影响其生成器吗?

时间:2013-03-01 14:23:57

标签: python for-loop python-2.7 generator side-effects

在Python v2.7中,我在for生成器上遇到for语句,其中在循环体中作为for生成器源的项是副作用:

for ssid in (ssid for ssid in overlaps if ssid != subseq_id):
  overlaps = subseq_id_to_overlap_ssids_dict[ssid]

我的问题是重叠的副作用是否会影响for发生器?我希望不是,但如果是这样,那究竟是什么意思呢?如果我已经处理了第一个匹配元素并现在替换为overlaps,那么for会将overlaps索引到新值的下一个位置吗?

2 个答案:

答案 0 :(得分:3)

在循环内重新绑定overlaps对循环没有任何影响(尽管显然会改变它)。在循环中重新绑定subseq_iq可能会影响生成器。

for循环计算表达式以在循环开始时获取迭代器一次:在这种情况下,表达式只是名称overlaps。一旦它评估了该表达式,它就会从iterable中创建一个迭代器,并使用该迭代器来处理这些元素。迭代器依赖于表达式返回的对象,它不依赖于用于标识该对象的名称(如果确实有任何名称)。

如果这种特殊情况,代码完全等同于:

for ssid in overlaps:
  if ssid != subseq_id:
     overlaps = subseq_id_to_overlap_ssids_dict[ssid]

这是一种更清晰的编写方式,但重新绑定overlaps并不会改变for使用的序列。

答案 1 :(得分:3)

for循环通过迭代其参数来操作,即在其参数上调用iter以生成迭代器,然后在迭代器上调用next,直到StopIteration被引发。< / p>

您的generator comprehension参数在输入overlaps循环之前计算名称表达式for,因此重新绑定名称overlaps将不起作用;变异overlaps引用的对象会产生一些影响,具体取决于type(overlaps)上的迭代器的运行方式。例如,list上的迭代器将索引增加到列表中。