I'm confused about the use of a double for loop in python, this is my code:
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
The output is this:
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
It only executes the inner loop for the first value of the outer loop, why is this happening? How can I get it to loop over all combinations of the first and second variable?
reversed()
produces an iterator; once you reach the end of an iterator, you can't re-use it:
>>> it = reversed([1, 2, 3])
>>> list(it)
[3, 2, 1]
>>> list(it)
[]
Create a new iterator for the nested loop:
for t1 in range1:
print t1
for t2 in reversed(range1):
print t1,t2
The reversed()
documentation links to the iterator glossary entry:
When no more data are available a
StopIteration
exception is raised instead. At this point, the iterator object is exhausted and any further calls to its__next__()
method just raiseStopIteration
again.
Bold emphasis mine.
In every implementation that respects pythons data model the result of reversed
can only be exhausted once (because it should return an iterator that is exhausted after the first traversal). After that iterator is exhausted it won't yield
any items anymore. But you can simply reverse your array using slicing:
range2 = np.linspace(1,6,10)[::-1]
for t1 in range1:
print t1
for t2 in range2:
print t1,t2
Basic slicing for numpy.array
s is very performant, it doesn't even need to copy the original.
Given that you use array
s you should be aware that iterating over them is a very slow operation because every value needs to be unboxed during the iteration. If you really need to iterate over one-dimensional array
s (hint: you generally don't) you should convert them to list
s:
range1 = np.linspace(1,6,10).tolist()
range2 = np.linspace(1,6,10)[::-1].tolist()
Because tolist
is more efficient at the unboxing compared to the (implicit) unboxing in a for
-loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With