508

How can you produce the following list with range() in Python?

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
ramesh.mimit
  • 9,445
  • 4
  • 21
  • 23

20 Answers20

782

Use reversed() function (efficient since range implements __reversed__):

reversed(range(10))

It's much more meaningful.

Update: list cast

If you want it to be a list (as @btk pointed out):

list(reversed(range(10)))

Update: range-only solution

If you want to use only range to achieve the same result, you can use all its parameters. range(start, stop, step)

For example, to generate a list [3, 2, 1, 0], you can use the following:

range(3, -1, -1)

It may be less intuitive, but it works the same with less text. This answer by @Wolf indicates this approach is slightly faster than reversed.

Intrastellar Explorer
  • 3,005
  • 9
  • 52
  • 119
Michał Šrajer
  • 30,364
  • 7
  • 62
  • 85
  • 14
    Although it 'is' less efficient. And you can't do slicing operations on it. – Jakob Bowyer Sep 02 '11 at 16:34
  • 4
    This would also produce a list from 8 down to 0, rather than 9 to 0. – Andrew Clark Sep 02 '11 at 16:41
  • This method is not generally applicable to strings (of hexadecimal numbers) which should be reversed. ;) – strpeter Oct 06 '14 at 13:56
  • 2
    This will cause memory to be allocated for the entire range which will be inefficient for large ranges or if you do not need all the values. `range(9, -1, -1)` or `xrange(9, -1, -1)` in Python 2 will give you an iterator. – Brice M. Dempsey Oct 24 '14 at 11:43
  • 6
    Using "reversed" with python generator (assuming we ware talking of Python 3 range built-in) is just conceptually wrong and teaches wrong habits of not considering memory/processing complexity when programming in high level language. – thedk Mar 23 '15 at 09:16
  • 1
    Since this answer is the top voted post, I think it's important we also mention the option with this answer, of using range by itself. i.e. range(limit, stop, step) i.e. range(n, -1, -1) Which may sound less intuitive but it's the right way to use range for reversed order. – Vishnu Narang Jan 21 '17 at 18:55
  • 17
    In Python3, `reversed` does not accept generators in general but it accepts `range`. Why would `reversed(range(10000))` need to allocate memory for the whole list? `range` can return an object that implements the `__reversed__` method that allows efficient reverse iteration? – avmohan Aug 05 '17 at 10:45
  • whats wrong with using reversed? I don't think I understand whats the issue with it... – Charlie Parker May 09 '18 at 19:21
  • Let's be pythonic and use list comp: `[i for i in range(5, -1, -1)]` – Sean Clarke Sep 01 '18 at 20:03
  • What about `[*range(5, -1, -1)]`? Super pythonic! – onofricamila Jun 08 '20 at 13:19
  • 1
    @CharlieParker If you want to turn an iterable into a list then `list(iterable)` \*is\* the Pythonic way to do it. `[i for i in ...]` is redundant for no reason. – Arthur Tacca Aug 10 '21 at 10:42
  • 2
    @thedk `range` is not a generator, and using `reversed(range(...))` is a perfectly reasonable thing to do – juanpa.arrivillaga Oct 05 '22 at 19:58
  • @SeanClarke that is *not pythonic*, `[x for x in whatever]`-> `list(whatever)` – juanpa.arrivillaga Oct 05 '22 at 19:58
365

Use the 'range' built-in function. The signature is range(start, stop, step). This produces a sequence that yields numbers, starting with start, and ending if stop has been reached, excluding stop.

>>> range(9,-1,-1)
    range(9, -1, -1)
>>> list(range(9,-1,-1))
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> list(range(-2, 6, 2))
    [-2, 0, 2, 4]

The list constructor converts range (which is a python generator), into a list.

  • 1
    Can you please explain this as well, also can you please recommend me any website/pdf book for python – ramesh.mimit Sep 02 '11 at 16:21
  • 9
    @ramesh If you run `help(range)` in a python shell it will tell you the arguments. They're the number to start on, the number to end on (exclusive), and the step to take, so it starts at 9 and subtracts 1 until it gets to -1 (at which point it stops without returning, which is why the range ends at 0) – Michael Mrozek Sep 02 '11 at 16:24
  • 3
    @ramesh.mimit: Just go to the official Python site. There is full documentation there, including a great tutorial. – John Y Sep 02 '11 at 16:55
  • 5
    Really, this is the proper answer, but it could be more clearly explained. `range(start, stop, step)` -- start at the number `start`, and yield results unless `stop` has been reached, moving by `step` each time. – Mr. B May 04 '15 at 21:33
  • Simple explanation: in order to go backwards, you need to set your `step` to be negative (add a minus sign) and your `start` to be bigger than the `stop` (`start` is your maximum, `stop` is your minimum). – tsveti_iko Mar 09 '22 at 15:16
58

You could use range(10)[::-1] which is the same thing as range(9, -1, -1) and arguably more readable (if you're familiar with the common sequence[::-1] Python idiom).

martineau
  • 119,623
  • 25
  • 170
  • 301
45

For those who are interested in the "efficiency" of the options collected so far...

Jaime RGP's answer led me to restart my computer after timing the somewhat "challenging" solution of Jason literally following my own suggestion (via comment). To spare the curious of you the downtime, I present here my results (worst-first):[1]

Jason's answer (maybe just an excursion into the power of list comprehension):

$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop

martineau's answer (readable if you are familiar with the extended slices syntax):

$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop

Michał Šrajer's answer (the accepted one, very readable):

$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop

bene's answer (the very first, but very sketchy at that time):

$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop

The last option is easy to remember using the range(n-1,-1,-1) notation by Val Neekman.


[1] As commented by Karl Knechtel, the results presented here are version-dependent and refer to the Python 3.x version that was stable at the time of answering this question.

Wolf
  • 9,679
  • 7
  • 62
  • 108
  • 4
    I did my own timings before reading this answer, and got the same results. – Todd Owen Jul 07 '18 at 19:36
  • 1
    These timings are useful but you haven't spelt out the conclusion: The time difference is so insignificant that you should use whichever is most readable and not worry about it. In fact the difference between the most readable (`reversed(...)`) and fastest/least readable (`range(9,-1,-1)`) is about a ten millionth of a second. Your users are not going to notice that :-) but will notice the bugs that could result from less readable code. – Arthur Tacca Aug 10 '21 at 10:52
  • 1
    Forgot to add: also they're pretty useless in this form because surely the bigger difference is going to be when you're iterating over millions of elements. 10 elements is too few to be particularly meaningful. – Arthur Tacca Aug 10 '21 at 10:56
  • 1
    All of this will depend on the Python version, since in 3.x `range` does not create a list. – Karl Knechtel Aug 04 '22 at 00:23
25

No sense to use reverse because the range function can return reversed list.

When you have iteration over n items and want to replace order of list returned by range(start, stop, step) you have to use third parameter of range which identifies step and set it to -1, other parameters shall be adjusted accordingly:

  1. Provide stop parameter as -1 (it's previous value of stop - 1, stop was equal to 0).
  2. As start parameter use n-1.

So equivalent of range(n) in reverse order would be:

n = 10
print range(n-1,-1,-1) 
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
martineau
  • 119,623
  • 25
  • 170
  • 301
Andriy Ivaneyko
  • 20,639
  • 6
  • 60
  • 82
  • 18
    Frankly I find this less intuitive than `reversed(range(n))` – Nicholas Hamilton Jan 11 '17 at 08:33
  • 2
    @NicholasHamilton Agree with you, however idea behind that answer is to use less resources... ( and the question was about using just range function :) ) – Andriy Ivaneyko Jan 11 '17 at 09:12
  • 1
    Ok, no worries, I guess it depends on the situation. For instance, If the range function is used as the index for a loop, then it will have limited effect, however, if it is used inside an external loop, then the cost will compound... – Nicholas Hamilton Jan 11 '17 at 23:32
15
for i in range(8, 0, -1)

will solve this problem. It will output 8 to 1, and -1 means a reversed list

Jutta
  • 513
  • 5
  • 13
  • 2
    This will give `8, 7, ... 1` instead of `8, 7, ... 0`. In way, this is a great answer, because it shows how bad the `range(..., -1)` techinique is. – Arthur Tacca Aug 10 '21 at 10:54
10

Readibility aside, reversed(range(n)) seems to be faster than range(n)[::-1].

$ python -m timeit "reversed(range(1000000000))"
1000000 loops, best of 3: 0.598 usec per loop
$ python -m timeit "range(1000000000)[::-1]"
1000000 loops, best of 3: 0.945 usec per loop

Just if anyone was wondering :)

  • good to have some numbers :) -- why didn't you add `range(1000000000-1,-1,-1)` as well? – Wolf Jun 13 '17 at 09:51
  • ...better don't try `timeit range(1000000000-1,-1,-1)` on the command line, instead see [my results](https://stackoverflow.com/a/44519681/2932052) :-) – Wolf Jun 13 '17 at 11:03
  • 1
    @Wolf these timings are version-specific, since in 3.x `range` does not create a list. `range(1000000000-1,-1,-1)` will actually be faster than either option in the question. – Karl Knechtel Aug 04 '22 at 00:25
10

Very often asked question is whether range(9, -1, -1) better than reversed(range(10)) in Python 3? People who have worked in other languages with iterators immediately tend to think that reversed() must cache all values and then return in reverse order. Thing is that Python's reversed() operator doesn't work if the object is just an iterator. The object must have one of below two for reversed() to work:

  1. Either support len() and integer indexes via []
  2. Or have __reversed__() method implemented.

If you try to use reversed() on object that has none of above then you will get:

>>> [reversed((x for x in range(10)))]
TypeError: 'generator' object is not reversible

So in short, Python's reversed() is only meant on array like objects and so it should have same performance as forward iteration.

But what about range()? Isn't that a generator? In Python 3 it is generator but wrapped in a class that implements both of above. So range(100000) doesn't take up lot of memory but it still supports efficient indexing and reversing.

So in summary, you can use reversed(range(10)) without any hit on performance.

Shital Shah
  • 63,284
  • 17
  • 238
  • 185
7

The requirement in this question calls for a list of integers of size 10 in descending order. So, let's produce a list in python.

# This meets the requirement.
# But it is a bit harder to wrap one's head around this. right?
>>> range(10-1, -1, -1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

# let's find something that is a bit more self-explanatory. Sounds good?
# ----------------------------------------------------

# This returns a list in ascending order.
# Opposite of what the requirement called for.
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# This returns an iterator in descending order.
# Doesn't meet the requirement as it is not a list.
>>> reversed(range(10))
<listreverseiterator object at 0x10e14e090>

# This returns a list in descending order and meets the requirement
>>> list(reversed(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Val Neekman
  • 17,692
  • 14
  • 63
  • 66
  • 3
    I really like the **triple `-1`** It's exactly *this pattern* that makes it easy to keep *`wrap one's head around this`* -- Today I learned that if it really *has to be efficient*, use `range(n-1, -1, -1)` when traversing a range in reversed order. – Wolf Jun 13 '17 at 11:09
6

You can do printing of reverse numbers with range() BIF Like ,

for number in range ( 10 , 0 , -1 ) :
    print ( number ) 

Output will be [10,9,8,7,6,5,4,3,2,1]

range() - range ( start , end , increment/decrement ) where start is inclusive , end is exclusive and increment can be any numbers and behaves like step

Mr. Suryaa Jha
  • 1,516
  • 16
  • 10
5

i believe this can help,

range(5)[::-1]

below is Usage:

for i in range(5)[::-1]:
    print i 
Sateesh Pagolu
  • 9,282
  • 2
  • 30
  • 48
dineshsprabu
  • 165
  • 3
  • 4
4
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
sanyassh
  • 8,100
  • 13
  • 36
  • 70
Asinox
  • 6,747
  • 14
  • 61
  • 89
  • 15
    Your answer shows why `reversed(range(10))` is less error-prone. No offence Asinox. Just an honest observation. – Michał Šrajer May 21 '13 at 16:47
  • I don't know if it is standard to leave erroneous answers on display. Can I or someone correct it or even remove it? – sinekonata May 20 '14 at 22:01
  • 3
    @sine, nope just leave it and wonder how it accumulated 3 upvotes... I suppose you could flag it for moderator attention (duplicate of [answer](http://stackoverflow.com/a/7286366/2742805) from 18 months earlier except broken), not sure whether or not they'd delete it. – OGHaza Jun 06 '14 at 10:23
  • For all future reference: [code only is not VLQ](https://meta.stackoverflow.com/q/256359/6296561), and [wrong answers aren't supposed to be flagged either](https://meta.stackexchange.com/a/202364/332043). Downvote and move on, but flagging is wrong in this case, whether NAA or mod-flagging. - [From review](https://stackoverflow.com/review/low-quality-posts/22882153) – Zoe Apr 29 '19 at 16:14
3

Using without [::-1] or reversed -

def reverse(text):
    result = []
    for index in range(len(text)-1,-1,-1):
        c = text[index]
        result.append(c)
    return ''.join(result)

print reverse("python!")
BrownRecluse
  • 1,638
  • 1
  • 16
  • 19
2

I thought that many (as myself) could be more interested in a common case of traversing an existing list in reversed order instead, as it's stated in the title, rather than just generating indices for such traversal.

Even though, all the right answers are still perfectly fine for this case, I want to point out that the performance comparison done in Wolf's answer is for generating indices only. So I've made similar benchmark for traversing an existing list in reversed order.

TL;DR a[::-1] is the fastest.

NB: If you want more detailed analysis of different reversal alternatives and their performance, check out this great answer.

Prerequisites:

a = list(range(10))

Jason's answer:

%timeit [a[9-i] for i in range(10)]
1.27 µs ± 61.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

martineau's answer:

%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Michał Šrajer's answer:

%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

bene's answer:

%timeit [a[i] for i in range(9, -1, -1)]
1.09 µs ± 11.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

As you see, in this case there's no need to explicitly generate indices, so the fastest method is the one that makes less extra actions.

NB: I tested in JupyterLab which has handy "magic command" %timeit. It uses standard timeit.timeit under the hood. Tested for Python 3.7.3

pkuderov
  • 3,501
  • 2
  • 28
  • 46
  • The case of `a[:: - 1]` turned out to be the fastest because you only counted the reversal time. If you write fairly: * Janson's answer: `%timeit [9-i for i in range (10)]` * martineau's answer: `%timeit list(range(10)) [:: - 1]` * Michał Šrajer's answer: `%timeit list(reversed(range(10)))` * bene's answer: `%timeit list(range(9, -1, -1))` Each of these solutions will give you a list. And the fastest solution, as @Wolf showed, is bene's answer => range (9, -1, -1) – Szczerski Dec 07 '20 at 15:16
  • @Szczerski now, let's imagine that `a = [3, 4, 100, 1, 20, -10, 0, 9, 5, 4]` in prerequisites. It brakes your code, but not mine. My answer is for the case when the __arbitrary__ list is already given – pkuderov Dec 08 '20 at 10:26
  • If you are looking for an answer to the question "Print a list in reverse order with range ()?" and you would like to know which way is the fastest. This solution is bene's answer. But if you are looking for the fastest way to reverse your list `a = [3, 4, 100, 1, 20, -10, 0, 9, 5, 4]` then use `reverse()` instead of `[:: - 1]`. `a.reverse ()` is twice as fast. – Szczerski Dec 09 '20 at 11:45
  • I disagree or I'm just still missing your point. Again, the answers to original question are mostly bound to `a = [0..9]` scenario. Timings from the popular answer may be misleading for more general cases. I needed timings for myself, so I did and shared them here. I didn't want in-place reversal - I needed just a plain list with a copy of the origin list in reverse order. Of course, this test is greatly simplified, and results may/should vary for a bit different test alternatives. – pkuderov Dec 11 '20 at 02:46
1
[9-i for i in range(10)]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Jason
  • 413
  • 5
  • 11
1

because range(n) produces an iterable there are all sorts of nice things you can do which will produce the result you desire, such as:

range(n)[::-1]

if loops are ok, we can make sort of a queue:

a = []
for i in range(n):
    a.insert(0,a)
return a

or maybe use the reverse() method on it:

reverse(range(n))
Dharman
  • 30,962
  • 25
  • 85
  • 135
Nadavo
  • 250
  • 2
  • 9
0

You don't necessarily need to use the range function, you can simply do list[::-1] which should return the list in reversed order swiftly, without using any additions.

  • This appears to be the solution suggested in a [previous answer](http://stackoverflow.com/a/21714738/1072229). It also appears that you might be trying to comment on a different previous answer -- you'll need to get a bit more reputation before you can do that. – Grisha Levit Jan 15 '17 at 07:15
0

Suppose you have a list call it a={1,2,3,4,5} Now if you want to print the list in reverse then simply use the following code.

a.reverse
for i in a:
   print(i)

I know you asked using range but its already answered.

-1
range(9,-1,-1)
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Is the correct form. If you use

reversed(range(10))

you wont get a 0 case. For instance, say your 10 isn't a magic number and a variable you're using to lookup start from reverse. If your n case is 0, reversed(range(0)) will not execute which is wrong if you by chance have a single object in the zero index.

-4

Get the reverse output of reversing the given input integer. example input is:5

The answer should be:

54321
1234
321
12
1

Answer is:

def get_val(n):
    d = ''.join(str(i) for i in range(n, 0, -1))
    print(d)
    print(d[::-1][:-1])
    if n - 1>1:
        return get_vale(n-1)
    
    
get_val(12)
    
ravi
  • 3
  • 2
  • 1
    Your answer does not address the question at all. Please review [how to answer](https://stackoverflow.com/help/how-to-answer). – AlexK Dec 27 '22 at 01:50