379

I am trying to loop from 100 to 0. How do I do this in Python?

for i in range (100,0) doesn't work.


For discussion of why range works the way it does, see Why are slice and range upper-bound exclusive?.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Joan Venge
  • 315,713
  • 212
  • 479
  • 689
  • 9
    BTW, you probably want to loop from 99 to 0, and rarely from 100 to 0. This affects the answers. – Asclepius Dec 04 '16 at 23:31
  • 1
    @Acumenus That was exactly what I searched for when reached here. And for the record the solution is to simply write: `range(100)[::-1]` (which is automatically translated to `range(9, -1, -1)`) - Tested in python 3.7 – Hassan Dec 02 '19 at 10:55

19 Answers19

539

Try range(100,-1,-1), the 3rd argument being the increment to use (documented here).

("range" options, start, stop, step are documented here)

nerak99
  • 640
  • 8
  • 26
0x6adb015
  • 7,473
  • 4
  • 24
  • 38
  • 3
    Also I need to use this to delete items from the collection, so that's why just wanted the indices. – Joan Venge May 15 '09 at 17:33
  • 4
    the second argument is one less than the final value. so if you put -1 then the range stops at 0, if you put -5, the range stops at -4 (for an increment of -1) – mulllhausen Jul 20 '14 at 14:01
244

In my opinion, this is the most readable:

for i in reversed(xrange(101)):
    print i,
Kenan Banks
  • 207,056
  • 34
  • 155
  • 173
  • 16
    This is better than the accepted answer since it doesn't actually allocate all the numbers in memory (in Python 3 the accepted answer wouldn't either), plus it's more obvious what is happening. – Blixt Mar 23 '12 at 13:52
  • 5
    Python before 2.6 does allocate all numbers, because reversed has no way to tell the xrange to go backwards... (Since Python 2.6 it calls __reversed__().) – Robert Siemer Jun 21 '12 at 18:31
  • 1
    I prefer `reversed(xrange(len(list)))` to `xrange(len(list)-1:-1:-1)`; the latter just looks weird with so many `-1`'s. – musiphil Sep 07 '13 at 01:13
  • @Blixt this is python, who cares about memory? – hacksoi Mar 20 '19 at 21:48
  • 2
    xrange() is not available anymore in Python 3 – Christopher Graf Sep 12 '19 at 06:38
  • 5
    In Python 3, `range` behaves the same way as `xrange` does in 2.7. @hacksoi depends on the use case but let's say you're iterating backwards in a large buffer, let's say it's 10 MB, then creating the reverse indices upfront would take seconds and use up over 50 MB of memory. Using a reversed generator would take milliseconds and only use up a few bytes of memory. – Blixt Sep 29 '19 at 06:23
50
for i in range(100, -1, -1)

and some slightly longer (and slower) solution:

for i in reversed(range(101))

for i in range(101)[::-1]
kcwu
  • 6,778
  • 4
  • 27
  • 32
19

Generally in Python, you can use negative indices to start from the back:

numbers = [10, 20, 30, 40, 50]
for i in xrange(len(numbers)):
    print numbers[-i - 1]

Result:

50
40
30
20
10
Blixt
  • 49,547
  • 13
  • 120
  • 153
18

Why your code didn't work

You code for i in range (100, 0) is fine, except

the third parameter (step) is by default +1. So you have to specify 3rd parameter to range() as -1 to step backwards.

for i in range(100, -1, -1):
    print(i)

NOTE: This includes 100 & 0 in the output.

There are multiple ways.

Better Way

For pythonic way, check PEP 0322.

This is Python3 pythonic example to print from 100 to 0 (including 100 & 0).

for i in reversed(range(101)):
    print(i)
mythicalcoder
  • 3,143
  • 1
  • 32
  • 42
  • 1
    yes, PEP-322 gives us a clear and least error-prone way to reverse iterations. – Allen Shen Jul 31 '19 at 20:25
  • 1
    This is good. The recommendation of how to implement `reversed` in PEP-322 is misleading, so it should be noted that `reversed` will call `__reversed__` on the iterable and return the result, and for `range` objects this is a lazy evaluated `range_object` iterator. In short: using this method is still lazy evaluation. – Ruzihm Oct 24 '19 at 16:07
6

Another solution:

z = 10
for x in range (z):
   y = z-x
   print y

Result:

10
9
8
7
6
5
4
3
2
1

Tip: If you are using this method to count back indices in a list, you will want to -1 from the 'y' value, as your list indices will begin at 0.

Andy T.
  • 61
  • 1
  • 1
4

The simple answer to solve your problem could be like this:

for i in range(100):
    k = 100 - i
    print(k)
enoted
  • 577
  • 7
  • 21
4

You might want to use the reversed function in python. Before we jump in to the code we must remember that the range function always returns a list (or a tuple I don't know) so range(5) will return [0, 1, 2, 3, 4]. The reversed function reverses a list or a tuple so reversed(range(5)) will be [4, 3, 2, 1, 0] so your solution might be:

for i in reversed(range(100)):
    print(i)
Adhrit
  • 59
  • 5
1

for var in range(10,-1,-1) works

krillgar
  • 12,596
  • 6
  • 50
  • 86
user2220115
  • 263
  • 6
  • 10
1

Short and sweet. This was my solution when doing codeAcademy course. Prints a string in rev order.

def reverse(text):
    string = ""
    for i in range(len(text)-1,-1,-1):
        string += text[i]
    return string    
1

You can always do increasing range and subtract from a variable in your case 100 - i where i in range( 0, 101 ).

for i in range( 0, 101 ):
    print 100 - i
pnoob
  • 19
  • 2
  • I like this method because Numba can't handle loops with `range(X,-1,-1)` but this way of structuring it works just fine. Sure a particular use case, but I couldn't think of this when staring at the loop, so thanks! – Matt Mar 03 '22 at 14:20
1

I wanted to loop through a two lists backwards at the same time so I needed the negative index. This is my solution:

a= [1,3,4,5,2]
for i in range(-1, -len(a), -1):
    print(i, a[i])

Result:

-1 2
-2 5
-3 4
-4 3
-5 1
Emanuel Lindström
  • 1,607
  • 16
  • 25
1

You can also create a custom reverse mechanism in python. Which can be use anywhere for looping an iterable backwards

class Reverse:
    """Iterator for looping over a sequence backwards"""
    def __init__(self, seq):
        self.seq = seq
        self.index = len(seq)

    def __iter__(self):
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index -= 1
        return self.seq[self.index]


>>> d = [1,2,3,4,5]
>>> for i in Reverse(d):
...   print(i)
... 
5
4
3
2
1
mohammed wazeem
  • 1,310
  • 1
  • 10
  • 26
0

I tried this in one of the codeacademy exercises (reversing chars in a string without using reversed nor :: -1)

def reverse(text):
    chars= []
    l = len(text)
    last = l-1
    for i in range (l):
        chars.append(text[last])
        last-=1

    result= ""   
    for c in chars:
        result += c
    return result
print reverse('hola')
0

Oh okay read the question wrong, I guess it's about going backward in an array? if so, I have this:

array = ["ty", "rogers", "smith", "davis", "tony", "jack", "john", "jill", "harry", "tom", "jane", "hilary", "jackson", "andrew", "george", "rachel"]


counter = 0   

for loop in range(len(array)):
    if loop <= len(array):
        counter = -1
        reverseEngineering = loop + counter
        print(array[reverseEngineering])
darrell
  • 63
  • 1
  • 4
  • It looks like your answer is the copy paste of the test you made. Please try to post a minimal example: the use of `global` and `time` is not relevant for the inital question. – Michael Doubez May 27 '19 at 21:06
0

Generally reversed() and [::-1] are the simplest options for existing lists. I did found this:

For a comparatively large list, under time constraints, it seems that the reversed() function performs faster than the slicing method. This is because reversed() just returns an iterator that iterates the original list in reverse order, without copying anything whereas slicing creates an entirely new list, copying every element from the original list. For a list with 10^6 Values, the reversed() performs almost 20,000 better than the slicing method. If there is a need to store the reverse copy of data then slicing can be used but if one only wants to iterate the list in reverse manner, reversed() is definitely the better option.

source: https://www.geeksforgeeks.org/python-reversed-vs-1-which-one-is-faster/

But my experiments do not confirm this:

For 10^5

$ python3 -m timeit -n 1000 -v "[x for x in range(100_000)[::-1]]"
raw times: 2.63 sec, 2.52 sec, 2.53 sec, 2.53 sec, 2.52 sec

1000 loops, best of 5: 2.52 msec per loop

$ python3 -m timeit -n 1000 -v "[x for x in reversed(range(100_000))]"
raw times: 2.64 sec, 2.52 sec, 2.52 sec, 2.52 sec, 2.51 sec

1000 loops, best of 5: 2.51 msec per loop

For 10^6

$ python3 -m timeit -n 1000 -v "[x for x in range(1_000_000)[::-1]]"
raw times: 31.9 sec, 31.8 sec, 31.9 sec, 32 sec, 32 sec

1000 loops, best of 5: 31.8 msec per loop

$ python3 -m timeit -n 1000 -v "[x for x in reversed(range(1_000_000))]"
raw times: 32.5 sec, 32 sec, 32.3 sec, 32 sec, 31.6 sec

1000 loops, best of 5: 31.6 msec per loop

Did I miss something?

But if you just wanna generate reversed list, there is no difference between reversed(range()) and range(n, -1, -1).

TenSzalik
  • 41
  • 4
-1

It works well with me

for i in range(5)[::-1]:
    print(i,end=' ')

output : 4 3 2 1 0

A DUBEY
  • 806
  • 6
  • 20
-1

Me, megamind:

i = 100
for j in range(0, 100):
   {do stuff}
   i -= 1
Mautoz
  • 29
  • 3
-2
a = 10
for i in sorted(range(a), reverse=True):
    print i
boomba
  • 68
  • 1
  • Welcome to Stack Overflow! Please consider editing your post to add more explanation about what your code does and why it will solve the problem. An answer that mostly just contains code (even if it's working) usually wont help the OP to understand their problem. – SuperBiasedMan Sep 22 '15 at 13:45
  • You realize that using `sorted` will needlessly store the entire list in memory, right? This is wasteful and is not feasible for large `a`. – Asclepius Dec 04 '16 at 23:28