98

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.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Joan Venge
  • 315,713
  • 212
  • 479
  • 689
  • 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
  • 2
    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
  • 2
    I'm not a fan of the insinuations there. Exactly as agf said: The request was to reverse "so I can iterate on it backwards". The other question speaks of reversing a list (which is already ambiguous between "reverse in place" and "create a reversed copy") and *also* "looping over it backwards", i.e., iterating backwards. The only techniques that don't equally apply to tuples are the ones that reverse in-place, and it will be obvious that they don't work to anyone who tries, and obvious *why* to anyone who *knows what a tuple is in the first place*. – Karl Knechtel Sep 10 '22 at 07:37
  • 2
    Redirecting people to a canonical improves the utility of the site. Novice Python programmers are *better served* by generalizing problems with sequences, rather than imagining that every little thing has to be done differently for lists vs tuples (vs. strings) - because the first is *much, much closer to the truth*. The answers here, mutatis mutandis, apply there (and would probably be duplicates, too). Anyway, if my philosophy were "deletionism", I would be casting delete votes. I reserve those for poorly asked or misleading questions that risk drawing traffic away from the better questions. – Karl Knechtel Sep 10 '22 at 07:38
  • (I will be happy to discuss the matter further on Meta or in the Python chat room, but not here.) – Karl Knechtel Sep 10 '22 at 07:42

3 Answers3

180

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
  • 27,347
  • 5
  • 42
  • 57
  • 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. – tripulse 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
  • 1
    @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
27

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
  • 14,854
  • 11
  • 100
  • 103
Praveen Gollakota
  • 37,112
  • 11
  • 62
  • 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
  • 138,105
  • 33
  • 200
  • 191