Ste*_*ven 4 python reverse loops for-loop nested
我对在python中使用double for循环感到困惑,这是我的代码:
import numpy as np
range1 = np.linspace(1,6,10)
range2 = reversed(np.linspace(1,6,10))
for t1 in range1:
print t1
for t2 in range2:
print t1,t2
Run Code Online (Sandbox Code Playgroud)
输出是这样的:
1.0
1.0 6.0
1.0 5.44444444444
1.0 4.88888888889
1.0 4.33333333333
1.0 3.77777777778
1.0 3.22222222222
1.0 2.66666666667
1.0 2.11111111111
1.0 1.55555555556
1.0 1.0
1.55555555556
2.11111111111
2.66666666667
3.22222222222
3.77777777778
4.33333333333
4.88888888889
5.44444444444
6.0
Run Code Online (Sandbox Code Playgroud)
它只对外循环的第一个值执行内循环,为什么会发生这种情况?如何让它循环遍历第一个和第二个变量的所有组合?
Mar*_*ers 10
reversed()产生一个迭代器 ; 一旦到达迭代器的末尾,就无法重复使用它:
>>> it = reversed([1, 2, 3])
>>> list(it)
[3, 2, 1]
>>> list(it)
[]
Run Code Online (Sandbox Code Playgroud)
为嵌套循环创建一个新的迭代器:
for t1 in range1:
print t1
for t2 in reversed(range1):
print t1,t2
Run Code Online (Sandbox Code Playgroud)
该reversed()文件链接到迭代器词汇的条目:
当没有更多数据可用时,
StopIteration会引发异常.此时,迭代器对象已耗尽,并且对其__next__()方法的任何进一步调用StopIteration再次引发.
大胆强调我的.
在每个尊重 python 数据模型的实现中, 的结果reversed只能被耗尽一次(因为它应该返回一个在第一次遍历后耗尽的迭代器)。迭代器耗尽后,它将不再有yield任何项目。但您可以使用切片简单地反转数组:
range2 = np.linspace(1,6,10)[::-1]
for t1 in range1:
print t1
for t2 in range2:
print t1,t2
Run Code Online (Sandbox Code Playgroud)
基本切片numpy.array非常高效,甚至不需要复制原始数据。
鉴于您使用了arrays,您应该意识到迭代它们是一个非常慢的操作,因为每个值都需要在迭代期间拆箱。如果您确实需要迭代一维arrays (提示:您通常不需要),您应该将它们转换为lists:
range1 = np.linspace(1,6,10).tolist()
range2 = np.linspace(1,6,10)[::-1].tolist()
Run Code Online (Sandbox Code Playgroud)
因为与循环tolist中的(隐式)拆箱相比,拆箱效率更高for。
reversed返回一个迭代器。迭代器只能被使用一次。
您在第一次迭代期间使用该迭代器。
要多次使用迭代器,您可以将其存储在list:
import numpy as np
range1 = np.linspace(1,6,10)
range2 = list(reversed(np.linspace(1,6,10))) # store in list
for t1 in range1:
print t1
for t2 in range2:
print t1,t2
Run Code Online (Sandbox Code Playgroud)
迭代器的好处之一是永远不会计算整个列表。您可以迭代超过 100 万个元素,而无需创建整个[0, 1, ..., 1000000]列表,如果您的算法期望在满足条件时跳出循环,那就更好了。
在像OP这样的简单情况下,列表很短,并且您知道您将迭代所有元素,因此使用列表非常简单且高效。