Python循环中的下一个迭代器

Python循环中的下一个迭代器,python,iterator,Python,Iterator,我有这样一个小程序: to_use = [True] * n val = 0 while (val is not None) : # various manipulations on val # so the val below is different from # val entering the loop to_use[val] = False val = next((i for i in range(n) if to_use[i]),None) 在我的示例

我有这样一个小程序:

to_use = [True] * n
val = 0
while (val is not None) :
   # various manipulations on val
   # so the val below is different from
   # val entering the loop
   to_use[val] = False
   val = next((i for i in range(n) if to_use[i]),None)

在我的示例中,
n
的数量级为百万。迭代器的最后一个like是获取下一个“
val
”的最有效方法吗?。还是每次在循环中都要通过
使用
from
0
?请注意,一旦
使用[i]=False
,它就永远不会重置为
True
,我建议每次只遍历一个循环项,并将其从True更改为False:

在Python 2中:

for i in xrange(len(to_use)):
    to_use[i] = False
在Python 3中:

for i in range(len(to_use)):
    to_use[i] = False

Python2中的xrange和Python3中的range是迭代器,因此您不会在列表[0..len(n)]中创建一个值。另一种方法是使用
设置
值:

to_use = set(range(n))

while len(to_use) > 0:
    val = min(to_use)
    # val manipulation here
    to_use.remove(val)

注意,这种方法需要在每次迭代时扫描所有剩余的值。平均而言,每次迭代,它扫描
n/2
值。根据列表中的哪些元素按哪个顺序设置为
False
,您最初的方法可能比这个方法快或慢。(如果您倾向于从列表末尾将内容设置为
False
,则您的方法可能已经更快。如果您倾向于从列表开头将内容设置为
False
,则此
set
方法可能更快。)

多亏了smarx在问题后的评论,我才能够解决这个问题。每次调用迭代器时,迭代器都会遍历
中的一百万个条目以使用它。因为我知道
to_use
条目在设置为
False
后不会更改,所以我编写了一个显式循环,跟踪上一个循环的结束位置,并从那里开始搜索

val = next((i for i in range(n) if to_use[i]),None)
cProfile显示了整个代码的208秒,其中大部分来自此行:

         900811 function calls in 208.227 seconds
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   199599  207.427    0.001  207.427    0.001 toposort.py:43(<genexpr>)

cProfile显示整个代码的时间为0.513秒

您只需在
中的每个值之间循环,以使用最后一行中的
val=0
。此操作终止的唯一原因是您将
设置为使用[0]
设置为
false
,因此
next
将为您提供
None
。认真地说,试着在每次迭代中打印
val
的值。它将在循环中每次从0开始执行
以使用
。@AkshatMahajan请阅读他的代码中的注释。不,它将是
i
的最小值,因此
以使用[i]
@smarx你是对的。
start = 0
to_use = [True] * n
val = 0
while (val is not None) :
   # various manipulations on val
   # so the val below is different from
   # val entering the loop
   to_use[val] = False
   val = None
   for i in range(start,n):
      if to_use[i]:
           val = i
           start = i
           break