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
”的最有效方法吗?。还是每次在循环中都要通过使用from0
?请注意,一旦使用[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