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
StopIterationexception is raised instead. At this point, the iterator object is exhausted and any further calls to its__next__()method just raiseStopIterationagain.
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.arrays is very performant, it doesn't even need to copy the original.
Given that you use arrays 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 arrays (hint: you generally don't) you should convert them to lists:
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