Python decreases for loop
Simulating an incremental C loop in Python style is very simple:
for (int i = A ; i < B ; i += C)
can be easily implemented in Python, No memory usage for array A to B using:
for i in range(A, B, C) # (xrange if Python 2.x)
But what about diminishing loops?
How can one simulate type C loops such as:
for (int i = A ; i >= B ; i -= C)
Even when used reversed(range(A, B, C))
builds the array in memory, since it reversed
must evaluate the entire generator first range
to return its values ββ...
Is there any trick for implementing such a for loop in Python, without creating an array in memory? Is there an equivalent for a generator range
that gives decreasing numbers?
source to share
range takes 3 arguments range(start,stop,step)
. The arg step can be negative to iterate backward.
arr = range(10) # range generator in python 3
for i in range(len(arr)-1,0,-1):
print(arr[i])
9
8
7
6
5
4
3
2
1
Note that the start len(arr)-1
is because lists are indexed 0, so the maximum idx is 9 for a list of length 10.
Negative steps don't have to be 1:
for i in range(len(arr)-1,0,-3):
print(arr[i])
9
6
3
In response to your second question, you can set arr to countdown from the beginning
arr = range(10,0,-1)
for a in arr: print(a)
10
9
8
7
6
5
4
3
2
1
source to share
Just go ahead and call reversed()
on result range()
. It will not build the entire list because the object range
has a method __reversed__
that the function reversed()
detects and uses.This is how you can see that it has this method:
>>> dir(range(3))
['__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index', 'start', 'step', 'stop']
This assumes you are using Python 3. Python 2 range
builds a list in memory regardless of whether you change it, although it has no performance difference most of the time. You can use xrange
which is similar to Python 3 range
and also has a method __reversed__
.
source to share