How can you loop over an iterable in reverse?
If you're working with a list, a string, or any other sequence in Python, you can reverse that sequence using Python's slicing syntax:
>>> colors = ["purple", "blue", "green", "pink", "red"]
>>> colors[::-1]
['red', 'pink', 'green', 'blue', 'purple']
The syntax looks weird, but it does work.
If we wanted to write a for loop that iterated over our list from the end to the beginning, we could loop over the reversed slice of that list:
>>> for color in colors[::-1]:
... print("I like", color)
...
I like red
I like pink
I like green
I like blue
I like purple
But this only works for sequences (meaning iterables that can be indexed).
Also, it looks a little bit weird.
reverse methodWhat about the reverse method?
Lists in Python have a reverse method.
The list reverse method will reverse a list in-place:
>>> colors = ["purple", "blue", "green", "pink", "red"]
>>> colors.reverse()
>>> colors
['red', 'pink', 'green', 'blue', 'purple']
But this method only exists on lists.
If we have a string, we could use the slicing syntax to reverse it:
>>> message = "Hello, World!"
>>> message[::-1]
'!dlroW ,olleH'
But we can't call its reverse method, because strings don't have a reverse method:
>>> message.reverse()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'reverse'
Also, the list reverse method is an in-place operation.
Meaning it doesn't return a new list to us, instead it modifies the original list.
If we wanted to loop in the reverse direction, without modifying our list, we could explicitly copy our list, reverse our copy, and then loop over our reversed copy:
>>> colors = ["purple", "blue", "green", "pink", "red"]
>>> reverse_colors = colors.copy()
>>> reverse_colors.reverse()
>>> for color in reverse_colors:
... print("I like", color)
...
I like red
I like pink
I like green
I like blue
I like purple
But that feels like a lot of work, just to loop in reverse. Fortunately, there's an even easier and more generic way to loop in reverse in Python!
reversed functionTo loop in the reverse direction, you can use Python's built-in reversed function:
>>> colors = ["purple", "blue", "green", "pink", "red"]
>>> for color in reversed(colors):
... print("I like", color)
...
I like red
I like pink
I like green
I like blue
I like purple
I find reversed a lot more readable than Python's slicing syntax, but it's also more flexible.
Python's slicing syntax only works on sequences, but reversed works on any reversible iterable!
The reversed function works on all sequences, but it also works on some other iterables, like dictionaries:
>>> capitals = {
... "New South Wales": "Sydney",
... ...
... "Victoria": "Melbourne",
... "Western Australia": "Perth",
... }
>>> for state, capital in reversed(capitals.items()):
... print(f"The capital of {state} is {capital}")
...
The capital of Western Australia is Perth
The capital of Victoria is Melbourne
...
The capital of New South Wales is Sydney
Dictionaries maintain the order of their items in insertion order, and you can loop over them in reverse by using the reversed function, even though they're not sequences.
reversed returns an iteratorThe reversed function accepts a reversible iterable, and it returns an iterator (a lazy iterable that generates items as we loop over it).
Iterators can be passed to the built-in next function to get just their next item:
>>> colors = ["purple", "blue", "green", "pink", "red"]
>>> r = reversed(colors)
>>> next(r)
'red'
>>> next(r)
'pink'
>>> next(r)
'green'
Due to the laziness of reversed, if we were to pass it lots of items (say 100,000 items) we won't end up copying the iterable that we gave it.
The reversed function just gives us a mechanism for tracking the last item and then the item just before that and so on:
>>> numbers = list(range(100_000))
>>> r = reversed(numbers)
>>> next(r)
99999
>>> next(r)
99998
>>> next(r)
99997
The reversed function only gives us the next item as we need it.
reversed is a looping helperYou can think of the reversed function as similar to Python's enumerate function:
>>> colors = ["purple", "blue", "green", "pink", "red"]
>>> for n, color in enumerate(colors, start=1):
... print(f"{n}. {color}")
...
1. purple
2. blue
3. green
4. pink
5. red
And similar to Python's zip function:
>>> states = ["New South Wales", "Queensland", "South Australia", "Tasmania", "Victo
ria", "Western Australia"]
>>> capitals = ["Sydney", "Brisbane", "Adelaide", "Hobart", "Melbourne", "Perth"]
>>> for state, capital in zip(states, capitals):
... print(f"{capital}, {state}")
...
Sydney, New South Wales
Brisbane, Queensland
Adelaide, South Australia
Hobart, Tasmania
Melbourne, Victoria
Perth, Western Australia
All three of these functions are looping helpers, meaning they don't store their results anywhere. Instead, these functions return objects that are meant to be looped over immediately.
reversed function to loop in reverseYou can't loop over all iterables in reverse in Python. For example, files and generators cannot be reversed.
But for iterables that can be reversed, you can use the built-in reversed function to loop backward.
We don't learn by reading or watching. We learn by doing. That means writing Python code.
Practice this topic by working on these related Python exercises.
Unlike, JavaScript, C, Java, and many other programming languages we don't have traditional C-style for loops.
Our for loops in Python don't have indexes.
This small distinction makes for some big differences in the way we loop in Python.
To track your progress on this Python Morsels topic trail, sign in or sign up.
Sign up for my 5 day email course and learn essential concepts that introductory courses often overlook!
Sign in to your Python Morsels account to track your progress.
Don't have an account yet? Sign up here.
Sign up for my free 5 day email course and learn essential concepts that introductory courses often overlook: iterables, callables, pointers, duck typing, and namespaces. Learn to avoid beginner pitfalls, in less than a week!
Ready to level up? Sign up now to begin your Python journey the right way!