Resources

See Sorting guide in the Python 3 docs.

Iterables

Sorted function

Using sorted built-in function to create a new list which is sorted. You can use it on a list, tuple or set but you always get a list.

On a list:

sorted([5, 2, 3, 1, 4])
# [1, 2, 3, 4, 5]

On a tuple:

>>> sorted (( 1,5, 3))
[1, 3, 5]

On a set:

>>> sorted({ 1 , 5, 3})
[1, 3, 5]

Some more practical list examples.

Here we keep both lists.

my_strings = ["abc", "xyz", "def"]

my_sorted_strings = sorted(my_strings)
my_sorted_strings
# ['abc', 'def', 'xyz']

Here we overwrite the original list.

my_strings = ["abc", "xyz", "def"]

my_strings = sorted(my_strings)
my_strings
# ['abc', 'def', 'xyz']

Neatly with a for loop:

my_strings = ["abc", "xyz", "def"]

for s in sorted(my_strings):
    print(s)

Sort method

Use list.sort method to modify in place. Only available on the list type.

a = [5, 2, 3, 1, 4]
a.sort()
a
# [1, 2, 3, 4, 5]
my_strings = ["abc", "xyz", "def"]

my_strings.sort()
my_strings
# ['abc', 'def', 'xyz']

List of dictionaries

If you try and apply sorted

Dictionaries

Applying sorted on dict will sort and return its keys only.

my_dict = {1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'}
sorted(my_dict)
# [1, 2, 3, 4, 5]

You can use dict.item to get a list of tuples (each with a key and value). If you sort that list, the key will be used first to sort on. If two items have the same key, then the value will also be used.

sorted(my_dict.items())
# [(1, 'D'), (2, 'B'), (3, 'B'), (4, 'E'), (5, 'A')]

You could use that like this, unpacking the two values of the tuple pair as key and value pairs.

for k, v in sorted(my_dict.items()):
    print(k, v)

# 1 D
# 2 B
# 3 B
# 4 E
# 5 A

Or iterate over the sorted keys and get the value too. This can be used to get keys and values together though.

my_dict = {1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'}

for k in sorted(my_dict):
     print(k, my_dict[k])
 
# 1 D
# 2 B
# 3 B
# 4 E
# 5 A

Sort functions

Specify a function for logic to sort by.,

Key functions

This works with both sorted and list.sort.

Supply a function to apply.

You can reference an existing function if you like.

str.lower

Or a Lambda anonymous function, such as to reference a class attribute or dictionary key or to compare a value numerically.

lambda x: x['name']

Here we sort a list as if all the elements were lowercase, but we keep the original values without actually storing any value as lowercase.

my_list = "This is a test string from Andrew".split()

sorted(my_list, key=str.lower)
# ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

Sort a list of class instances by the age attribute:

class Student:

    def __init__(self, name, grade, age):
        self.name = name
        self.grade = grade
        self.age = age

    def __repr__(self):
        return repr((self.name, self.grade, self.age))


student_objects = [
    Student('john', 'A', 15),
    Student('jane', 'B', 12),
    Student('dave', 'B', 10),
]

sorted(student_objects, key=lambda student: student.age)
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

Operator module functions

These are easier and faster than key functions from above.

from operator import itemgetter


sorted(student_objects, key=itemgetter(2))
# [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

Or

from operator import attrgetter


sorted(student_objects, key=attrgetter('age'))
# [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

The operator module functions allow multiple levels of sorting. For example, to sort by grade then by age:

sorted(student_objects, key=itemgetter(1, 2))
# [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
sorted(student_objects, key=attrgetter('grade', 'age'))
# [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

Reverse

Reverse function

This returns an iterator, so remember to use convert to a list or use in a for loop.

my_strings = ['abc', 'def', 'xyz']

reversed(my_strings)
# <list_reverseiterator object at 0x10f343a90>

list(reversed(my_strings))
# ['xyz', 'def', 'abc']

Reversed method

my_strings = ['abc', 'def', 'xyz']

my_strings.reversed()

my_strings
# ['xyz', 'def', 'abc']