89

Possible Duplicate:
Traverse a list in reverse order in Python

Is this possible? Doesn't have to be in place, just looking for a way to reverse a tuple so I can iterate on it backwards.

Community
  • 1
  • 1
Joan Venge
  • 292,935
  • 205
  • 455
  • 667
  • 5
    Have you tried using `reversed` ? – Wes Apr 18 '12 at 02:30
  • There are lots of duplicates of this question, but they all seem to be asking about strings or lists istead of tuples. The answer is the same. Examples: http://stackoverflow.com/questions/931092/reverse-a-string-in-python http://stackoverflow.com/questions/6827413/reverse-does-not-work-on-a-python-literal http://stackoverflow.com/questions/529424/traverse-a-list-in-reverse-order-in-python – agf Apr 18 '12 at 02:35
  • 1
    This is not the same as reversing lists and imo stands as a reasonable question. There are additional considerations for `tuple`s including invoking `tuple()` on the outut. – WestCoastProjects Apr 20 '20 at 18:47

3 Answers3

162

There are two idiomatic ways to do this:

reversed(x)  # returns an iterator

or

x[::-1]  # returns a new tuple

Since tuples are immutable, there is no way to reverse a tuple in-place.


Edit: Building on @lvc's comment, the iterator returned by reversed would be equivalent to

def myreversed(seq):
    for i in range(len(x) - 1, -1, -1):
        yield seq[i]

i.e. it relies on the sequence having a known length to avoid having to actually reverse the tuple.

As to which is more efficient, i'd suspect it'd be the seq[::-1] if you are using all of it and the tuple is small, and reversed when the tuple is large, but performance in python is often surprising so measure it!

tobyodavies
  • 25,120
  • 5
  • 39
  • 56
  • 2
    If you actually need to construct an output tuple, then you need to compare `tuple(reversed(x))` to `x[::-1]` for performance. If you simply want to iterate over the elements in reverse order, `reversed` has a much better chance of showing a performance improvement. – Karl Knechtel Apr 18 '12 at 06:35
  • 1
    `reversed` is 21% faster for large tuples and 3% slower for small tuples. Since it's much more readable, I would use `reversed` for everything. I did `timeit.timeit("for i in x[::-1]: i * i", "x = tuple(range(1000000))", number=1000)` and `timeit.timeit("for i in x[::-1]: i * i", "x = tuple(range(3))", number=100000)`. – Boris Verkhovskiy Apr 09 '19 at 15:13
  • I prefer the `x[::-1]` one because it's handy. – ayesbee Apr 21 '19 at 16:52
  • @tobyodavies this one is beautiful: ```x[::-1]```. Such extended slices are well explained here: https://docs.python.org/release/2.3.5/whatsnew/section-slices.html. – Mike Feb 12 '20 at 13:28
  • This is not a direct answer to the question given that the output is an `list_reverseiteator` – WestCoastProjects Apr 20 '20 at 18:48
  • What are you talking about @javadba the second one is a tuple. Also the question says it wants to iterate over the tuple backwards. At no point does it say they actually want a tuple but I gave both an iterator and a tuple as possible return types. – tobyodavies Apr 30 '20 at 19:07
  • Fair enough - I should have just commented instead that the first one would be better stated as `tuple(reversed(x))` as in the following answer. Not all of us will realize immediately that the `list_reverseiterator` simply needs `tuple` around it to get a list out of it. I agree the downvote were not warranted but I can not "reverse" it unless the answer is changed due to SOF rules aimed at handling abuse - but which are problematic in normal non-abuse situations such as this. I generally disagree with `python3` having turned results into generators: it seriously decreases readability. – WestCoastProjects Apr 30 '20 at 19:15
  • @javadba the question asks how to reverse a tuple (the input), it makes no statement as to the desired type of the output. It says they want to iterate over it backwards, in which case an iterator may be a more appropriate type. Hence the deliberate choice not to unnecessarily create a tuple, but to clearly provide the second option in case they did in fact want a tuple but did not say so. – tobyodavies May 08 '20 at 19:47
  • If the tuples are of known length and really short it can even be more efficient to do the reversal explicitly: ```import timeit print(timeit.timeit("(t[1], t[0])", "t = (1337, 42)", number=1000)) print(timeit.timeit("t[::-1]", "t = (1337, 42)", number=1000))``` – Harald Husum Oct 26 '20 at 11:14
25

You can use the reversed builtin function.

>>> x = (1, 2, 3, 4)
>>> x = tuple(reversed(x))
>>> x
(4, 3, 2, 1)

If you just want to iterate over the tuple, you can just use the iterator returned by reversed directly without converting it into a tuple again.

>>> for k in reversed(x):
...     print(k)
... 
4 3 2 1
Boris Verkhovskiy
  • 10,733
  • 7
  • 77
  • 79
Praveen Gollakota
  • 33,984
  • 10
  • 60
  • 61
7

Similar to the way you would reverse a list, i.e. s[::-1]

In [20]: s = (1, 2, 3)

In [21]: s[::-1]
Out[21]: (3, 2, 1)

and

In [24]: for i in s[::-1]:
   ....:     print i
   ....:
3
2
1
Levon
  • 129,246
  • 33
  • 194
  • 186