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?

+3


source to share


2 answers


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

      

+3


source


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__

.

+2


source







All Articles