Python sort list

Алан-э-Дейл       10.05.2022 г.

Метод sorted() для других типов данных

Еще одно ключевое различие между и заключается в том, что метод принимает любые итерируемые объекты (списки, строки, кортежи и т.д.), тогда как метод работает только со списками.

Давайте разобьём строку на отдельные слова с помощью метода , а затем используем метод для сортировки слов по длине от наименьшего к наибольшему.

my_sentence = "Jessica found a dollar on the ground"

# Вывод оригинального предложения: 
print("Original sentence: ", my_sentence)

# Вывод отсортированного списка слов:
print(sorted(my_sentence.split(), key=len))

# Результат:
# Original sentence:  Jessica found a dollar on the ground
# 

А теперь давайте чуть изменим наш пример. Добавим необязательный аргумент . Благодаря этому список будет отсортирован в обратном порядке, от самого длинного слова к самому короткому.

my_sentence = "Jessica found a dollar on the ground"

print("Original sentence: ", my_sentence)
print(sorted(my_sentence.split(), key=len, reverse=True))

# Результат:
# Original sentence:  Jessica found a dollar on the ground
# 

Мы также можем использовать метод и для кортежей.

В этом примере у нас есть набор кортежей, которые представляют имя, возраст и музыкальный инструмент учащихся какой-то группы.

band_students = 

Мы можем использовать метод для сортировки этих данных по возрасту учащегося. Аргумент будет иметь значение лямбда-функции, которая сообщает компьютеру о сортировке по возрасту в порядке возрастания.

Лямбда-функция – это анонимная функция. Этот тип функции можно определить с помощью ключевого слова .

Итак, напишем следующую лямбду-функцию, которая будет говорить нашей программе, что отсортировать мы хотим именно по возрасту:

lambda student: student

Чтобы получить доступ к значению в кортеже, мы используем квадратные скобки и индекс элемента в кортеже, к которому хотим получить доступ. Поскольку в Python отсчет идет с нуля, возраст у нас будет под индексом .

Таким образом, мы получаем следующий код:

band_students = 

print(sorted(band_students, key=lambda student: student))

# Результат:
# 

Мы можем изменить этот пример. Давайте отсортируем кортежи по названиям музыкальных инструментов. Более того, давайте используем для сортировки инструментов в обратном алфавитном порядке.

band_students = 

print(sorted(band_students, key=lambda student: student, reverse=True))

# Результат:
# 

Sort a Dictionary in Python by Key

Method 1: Use operator.itemgetter() (Recommended method for older versions of Python)

Now, if you want to sort a Dictionary by Key, we can use the method, like in the last section. The only change that we have to make is to sort the list based on keys now, so we call .

import operator

my_dict = {2: 10, 1: 2, -3: 1234}

# Sort the Dict based on keys
sorted_dict = dict(sorted(my_dict.items(), key=operator.itemgetter(0)))

print(sorted_dict)

Output

{-3: 1234, 1: 2, 2: 10}

Indeed, the dictionary has been sorted based on the Key now!

Method 2: Use sorted() with a lambda (Recommended method for Python 3.6+)

We can again use the method, with a lambda, on newer versions of Python.

Again, this is the same as before, but we’ll be now sorting based on value.

my_dict = {2: 10, 1: 2, -3: 1234}
sorted_dict = dict(sorted(my_dict.items(), key=lambda item: item))

Output

{-3: 1234, 1: 2, 2: 10}

Again, the output is the same as before.

Сортировать с помощью настраиваемой функции с помощью клавиши

Если вам нужна собственная реализация для сортировки, метод sort() также принимает ключевую функцию в качестве необязательного параметра.

По результатам ключевой функции вы можете отсортировать данный список.

list.sort(key=len)

В качестве альтернативы для сортировки:

sorted(list, key=len)

Здесь len ‒ это встроенная функция Python для подсчета длины элемента.

Список сортируется по длине каждого элемента от наименьшего количества к наибольшему.

Мы знаем, что кортеж по умолчанию сортируется по первому параметру. Давайте посмотрим, как настроить метод для сортировки с использованием второго элемента.

Оптимизация

Мы можем улучшить производительность алгоритма сортировки слиянием. Сначала давайте поймем разницу между сортировкой слияния сверху вниз и снизу вверх. Подход снизу вверх сортирует элементы смежных списков итеративно, а подход сверху вниз разбивает списки на две половины.

Данный список , вместо того, чтобы разбивать его на , , , , , – мы делим в подсписки, которые уже могут быть отсортированы: , , , и теперь готовы их отсортировать.

Сортировка слиянием – неэффективный алгоритм как во времени, так и в пространстве для меньших подсписков. Таким образом, сортировка вставкой является более эффективным алгоритмом, чем сортировка слиянием для меньших подсписков.

Stable sort

A stable sort is one where the initial order of equal elements is preserved.
Some sorting algorithms are naturally stable, some are unstable. For instance, the
merge sort and the bubble sort are stable sorting algorithms. On the other hand, heap
sort and quick sort are examples of unstable sorting algorithms.

Consider the following values: . A stable sorting
produces the following: . The ordering of the values
3 and 5 is kept. An unstable sorting may produce the following: .

Python uses the timsort algorithm. It is a hybrid stable sorting algorithm,
derived from merge sort and insertion sort. It was implemented by Tim Peters
in 2002 for use in the Python programming language.

Сортировка выборкой

Этот алгоритм сегментирует список на две части: отсортированную и неотсортированную. Наименьший элемент удаляется из второго списка и добавляется в первый.

Алгоритм

На практике не нужно создавать новый список для отсортированных элементов. В качестве него используется крайняя левая часть списка. Находится наименьший элемент и меняется с первым местами.

Теперь, когда нам известно, что первый элемент списка отсортирован, находим наименьший элемент из оставшихся и меняем местами со вторым. Повторяем это до тех пор, пока не останется последний элемент в списке.

Реализация

def selection_sort(nums):  
    # Значение i соответствует кол-ву отсортированных значений
    for i in range(len(nums)):
        # Исходно считаем наименьшим первый элемент
        lowest_value_index = i
        # Этот цикл перебирает несортированные элементы
        for j in range(i + 1, len(nums)):
            if nums < nums:
                lowest_value_index = j
        # Самый маленький элемент меняем с первым в списке
        nums, nums = nums, nums

# Проверяем, что оно работает
random_list_of_nums =   
selection_sort(random_list_of_nums)  
print(random_list_of_nums) 

По мере увеличения значения  нужно проверять меньше элементов.

Обзор и требования

Мы будем предполагать , что вы уже знаете, по крайней мере, что-то об алгоритмах сортировки и познакомились с идеей быстрой сортировки. К концу этого урока вы должны лучше понять, как это работает.

Мы также предположим, что вы рассмотрели некоторые более фундаментальные концепции информатики, особенно , на которые опирается Quicksort.

Напомним, что Quicksort является одним из наиболее эффективных и наиболее часто используемых алгоритмов сортировки списка чисел. В отличие от своего конкурента, Mergesort, Quicksort может сортировать список на месте, без необходимости создавать копию списка и, следовательно, экономить требования к памяти.

Основная интуиция, лежащая в основе Quicksort, заключается в том, что если мы можем эффективно разделять список, то мы можем эффективно сортировать его. Разбиение списка на разделы означает, что мы выбираем элемент pivot в списке, а затем изменяем список, чтобы переместить все элементы, большие, чем pivot, вправо, а все меньшие элементы-влево.

После того, как сводная точка будет выполнена, мы можем выполнить ту же операцию с левой и правой частями списка рекурсивно, пока список не будет отсортирован.

Вот реализация Quicksort на Python. Прочтите его и посмотрите, имеет ли это смысл. Если нет, читайте ниже!

def partition(xs, start, end):
    follower = leader = start
    while leader < end:
        if xs <= xs:
            xs, xs = xs, xs
            follower += 1
        leader += 1
    xs, xs = xs, xs
    return follower

def _quicksort(xs, start, end):
    if start >= end:
        return
    p = partition(xs, start, end)
    _quicksort(xs, start, p-1)
    _quicksort(xs, p+1, end)
    
def quicksort(xs):
    _quicksort(xs, 0, len(xs)-1)

Python sort list of custom complex objects — bags of coins

We have a custom object, a namedtuple, which has a specific way to sort it.

Note: According to the Python documentation, the and
use only the magic method when doing sorting. So we
need to implement only this method. However, the PEP8 recommends to implement all six operations
( , , , , ,
) for safety and code completeness.

The decorator from the module helps to reduce
the boilerplate. The requires the and one of the
remaining methods to be implemented.

sort_coins.py

#!/usr/bin/env python3

from typing import NamedTuple
from functools import total_ordering

# a gold coin equals to two silver and six bronze coins


class Coin(NamedTuple):

    rank: str


@total_ordering
class Pouch:

    def __init__(self):
        self.bag = []

    def add(self, coin):

        self.bag.append(coin)

    def __eq__(self, other):

        val1, val2 = self.__evaluate(other)

        if val1 == val2:
            return True
        else:
            return False        

    def __lt__(self, other):

        val1, val2 = self.__evaluate(other)

        if val1 < val2:
            return True
        else:
            return False

    def __str__(self):

        return f'Pouch with: {self.bag}'

    def __evaluate(self, other):

        val1 = 0
        val2 = 0

        for coin in self.bag:

            if coin.rank == 'g':
                val1 += 6

            if coin.rank == 's':
                val1 += 3

            if coin.rank == 'b':
                val1 += 1

        for coin in other.bag:

            if coin.rank == 'g':
                val2 += 6

            if coin.rank == 's':
                val2 += 3

            if coin.rank == 'b':
                val2 += 1

        return val1, val2


def create_pouches():

    p1 = Pouch()

    p1.add(Coin('g'))
    p1.add(Coin('b'))
    p1.add(Coin('s'))

    p2 = Pouch()

    p2.add(Coin('g'))
    p2.add(Coin('s'))

    p3 = Pouch()

    p3.add(Coin('b'))
    p3.add(Coin('s'))
    p3.add(Coin('s'))

    p4 = Pouch()

    p4.add(Coin('b'))
    p4.add(Coin('s'))

    p5 = Pouch()

    p5.add(Coin('g'))
    p5.add(Coin('s'))
    p5.add(Coin('s'))
    p5.add(Coin('b'))
    p5.add(Coin('b'))
    p5.add(Coin('b'))

    p6 = Pouch()

    p6.add(Coin('b'))
    p6.add(Coin('b'))    
    p6.add(Coin('b'))    
    p6.add(Coin('b'))    
    p6.add(Coin('b'))   

    p7 = Pouch()
    p7.add(Coin('g'))

    p8 = Pouch()
    p8.add(Coin('g'))
    p8.add(Coin('g'))
    p8.add(Coin('s'))

    bag = 

    return bag


bag = create_pouches()
bag.sort()

for e in bag:
    print(e)

In the example, we sort pouches of coins. There are three types
of coins: gold, silver, and bronze. One gold coin equals to two silver
and six bronze coins. (Therefore, one silver coin equals to three bronze coins.)

class Coin(NamedTuple):

    rank: str

Our custom object is a namedtuple, which has one attribute: .

@total_ordering
class Pouch:

    def __init__(self):
        self.bag = []

    def add(self, coin):

        self.bag.append(coin)
...

The has an internal list for storing its coins.
In the class, we have two comparison methods: and .
The decorator supplies the rest.

def __lt__(self, other):

    val1, val2 = self.__evaluate(other)

    if val1 < val2:
        return True
    else:
        return False

The method is used by the Python sorting functions
to compare two objects. We have to compute the value of all coins in
two pouches and compare them.

def __str__(self):

    return f'Pouch with: {self.bag}'

The gives the human-readable representation
of the object.

def __evaluate(self, other):

    val1 = 0
    val2 = 0

    for coin in self.bag:

        if coin.rank == 'g':
            val1 += 6

        if coin.rank == 's':
            val1 += 3

        if coin.rank == 'b':
            val1 += 1

    for coin in other.bag:

        if coin.rank == 'g':
            val2 += 6

        if coin.rank == 's':
            val2 += 3

        if coin.rank == 'b':
            val2 += 1

    return val1, val2

The method calculates the values of
the two pouches. It returns both values to the
for comparison.

def create_pouches():

    p1 = Pouch()

    p1.add(Coin('g'))
    p1.add(Coin('b'))
    p1.add(Coin('s'))

    p2 = Pouch()

    p2.add(Coin('g'))
    p2.add(Coin('s'))
...

In the function we create eight pouches
with various amounts of coins.

bag.sort()

for e in bag:
    print(e)

We sort the bag of pouches and then print the elements of the
sorted bag.

$ ./coins.py 
Pouch with: 
Pouch with: 
Pouch with: 
Pouch with: 
Pouch with: 
Pouch with: 
Pouch with: 
Pouch with: 

This is the output. The pouch with two gold coins and one silver coin is the most
valuable.

In this tutorial, we have covered sorting operations on lists in Python.

List .

Что означает “на месте” и “стабильно”?

  • На месте: алгоритм на месте требует дополнительного пространства, не обращая внимания на размер ввода коллекции. После выполнения сортировки он перезаписывает исходные ячейки памяти элементов в коллекции.
  • Стабильный: это термин, который управляет относительным порядком равных объектов в исходном массиве.

Что более важно, сортировка вставкой в Python не требует заранее знать размер массива, и она получает по одному элементу за раз. В сортировке вставкой замечательно то, что если мы вставляем больше элементов для сортировки, алгоритм размещает их в нужном месте, не выполняя полную сортировку

В сортировке вставкой замечательно то, что если мы вставляем больше элементов для сортировки, алгоритм размещает их в нужном месте, не выполняя полную сортировку.

Это более эффективно для массива небольшого (менее 10) размера. Теперь давайте разберемся с концепцией сортировки вставкой.

Пользовательская логика для сортировки списка

Мы также можем реализовать вашу собственную логику для сортировки элементов списка.

В последнем примере мы использовали возраст как ключевой элемент для сортировки нашего списка.

Но есть такая поговорка: «Сначала дамы!». Итак, мы хотим отсортировать наш список таким образом, чтобы женский пол имел приоритет над мужским. Если пол двух человек совпадает, младший получает более высокий приоритет.

Итак, мы должны использовать ключевой аргумент в нашей функции сортировки. Но функцию сравнения нужно преобразовать в ключ.

Итак, нам нужно импортировать библиотеку под названием functools. Мы будем использовать функцию cmp_to_key(), чтобы преобразовать compare_function в key.

import functools


def compare_function(person_a, person_b):
    if person_a == person_b:  # if their gender become same
        return person_a - person_b  # return True if person_a is younger
    else:  # if their gender not matched
        if person_b == 'F':  # give person_b first priority if she is female
            return 1
        else:  # otherwise give person_a first priority
            return -1

persons = , , , ]

print(f'Before sorting: {persons}')

persons.sort(key=functools.cmp_to_key(compare_function))

print(f'After sorting: {persons}')

Вывод:

Before sorting: , , , ]
After sorting: , , , ]

Список сначала сортируется по полу. Затем он сортируется по возрасту людей.

Концепция сортировки вставкой

Массив разделился практически на две части при сортировке вставками – несортированная часть и отсортированная часть.

Отсортированная часть содержит первый элемент массива, а другая несортированная часть содержит остальную часть массива. Первый элемент в несортированном массиве сравнивается с отсортированным массивом, чтобы мы могли поместить его в соответствующий подмассив.

Он фокусируется на вставке элементов путем перемещения всех элементов, если правое значение меньше левого.

Это будет повторяться до тех пор, пока весь элемент не будет вставлен в правильное место.

Ниже приведен алгоритм сортировки массива с помощью вставки.

  • Разбить список на две части – отсортированный и несортированный.
  • Итерировать от arr к arr по заданному массиву.
  • Сравнить текущий элемент со следующим элементом.
  • Если текущий элемент меньше, чем следующий элемент, сравнить с предыдущим элементом. Переместиться к большим элементам на одну позицию вверх, чтобы освободить место для замененного элемента.

Разберемся в следующем примере.

Рассмотрим первый элемент отсортированного массива.

Первый шаг к добавлению 10 в отсортированный подмассив.

Теперь берем первый элемент из несортированного массива – 4. Это значение сохраняем в новой переменной temp. Теперь мы видим, что 10> 4, перемещаем 10 вправо, и это перезаписывает 4, которые были ранее сохранены.

(темп = 4)

Здесь 4 меньше, чем все элементы в отсортированном подмассиве, поэтому мы вставляем его в первую позицию индекса.

У нас есть два элемента в отсортированном подмассиве.

Теперь проверьте число 25. Мы сохранили его во временной переменной. 25> 10, а также 25> 4, затем мы помещаем его в третью позицию и добавляем в отсортированный подмассив.

Снова проверяем цифру 1. Сохраняем в темп. 1 меньше 25. Он перезаписывает 25.

10> 1, затем перезаписывается снова

4> 1 теперь ставим значение temp = 1

Теперь у нас есть 4 элемента в отсортированном подмассиве. 5 <25, затем сместите 25 в правую сторону и передайте temp = 5 в левую сторону.

положите temp = 5

Теперь мы получаем отсортированный массив, просто помещая временное значение.

Данный массив отсортирован.

Реализация

Python предоставляет встроенные функции для сортировки элементов с использованием сортировки по куче. Функции приведены ниже.

  • heappush(list, item) – используется для добавления элемента кучи и его повторной сортировки.
  • heappop(список) – нужна для удаления и возврата элемента.
  • heapfy() – используется для превращения данного списка в кучу.

Рассмотрим следующий пример сортировки кучей.

Пример –

from heapq import heappop, heappush  
   
 def heapsort(list1):  
     heap = []  
     for ele in list1:  
         heappush(heap, ele)  
   
     sort = []  
   
     # the elements are lift in the heap  
     while heap:  
         sort.append(heappop(heap))  
   
     return sort  
   
 list1 =   
 print(heapsort(list1))  

Выход:

Объяснение:

В приведенном выше коде мы импортировали модуль heapq, который состоит из методов heappop() и heappush(). Мы создали метод Heapsort Heapsort(), который принимает list1 в качестве аргумента. Цикл for выполняет итерацию по списку 1 и помещает элементы в пустую кучу. Мы использовали цикл while и добавили отсортированный элемент к пустой сортировке.

Мы вызвали функцию Heapsort Heapsort() и передали список. Он вернул отсортированный список.

The Old Way Using the cmp Parameter

Many constructs given in this HOWTO assume Python 2.4 or later. Before that, there was no sorted() builtin and list.sort() took no keyword arguments. Instead, all of the Py2.x versions supported a cmp parameter to handle user specified comparison functions.

In Py3.0, the cmp parameter was removed entirely (as part of a larger effort to simplify and unify the language, eliminating the conflict between rich comparisons and the __cmp__ methods).

In Py2.x, sort allowed an optional function which can be called for doing the comparisons. That function should take two arguments to be compared and then return a negative value for less-than, return zero if they are equal, or return a positive value for greater-than. For example, we can do:

>>> def numeric_compare(x, y):
        return x - y
>>> sorted(, cmp=numeric_compare)

Or you can reverse the order of comparison with:

>>> def reverse_numeric(x, y):
        return y - x
>>> sorted(, cmp=reverse_numeric)

When porting code from Python 2.x to 3.x, the situation can arise when you have the user supplying a comparison function and you need to convert that to a key function. The following wrapper makes that easy to do:

def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K(object):
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K

To convert to a key function, just wrap the old comparison function:

>>> sorted(, key=cmp_to_key(reverse_numeric))

In Python 2.7, the cmp_to_key() tool was added to the functools module.

Пример 1. Сортировка списка чисел в формате строковых данных

Напишем код для сортировки списка строковых данных, которые являются числами, с применением лямбда-функции.

Зададим список из 6 элементов. Лямбду будем использовать внутри функции для сортировки списка.

В качестве первого аргумента функции указывается переменная списка, лямбда устанавливается ​​в качестве значения ключа, а третьим аргументом передается начальная позиция сортировки. При помощи выводим в консоль отсортированный список через пробел.

n_list = 
# Sort the list using lambda and sorted function
sorted_list = sorted(n_list, key=lambda x: int(x))
# Print the sorted list
print("The list of the sorted values are:")
for value in sorted_list:
    print(value, end=' ')

Запустив наш код, получим следующий результат.

The list of the sorted values are:
1 5 11 19 37 50 

Python sort list of grades

There are various grading systems around the world. Our example contains
grades such as A+ or C- and these cannot be ordered lexicographically. We use
a dictionary where each grade has its given value.

grades.py

#!/usr/bin/env python3


data = 'A+ A A- B+ B B- C+ C C- D+ D'
grades = { grade: idx for idx, grade in enumerate(data.split()) } 

def mc(e):
    return grades.get(e)

students = 

print(grades)

students.sort(key=mc)
print(students)


# from operator import itemgetter
# students.sort(key=lambda e: itemgetter(e)(grades))

We have a list of students. Each student has a name and a grade in a nested
tuple.

data = 'A+ A A- B+ B B- C+ C C- D+ D'
grades = { grade: idx for idx, grade in enumerate(data.split()) } 

We build the dictionary of grades. Each grade has its value. The grades will
be sorted by their dictionary value.

def mc(e):
    return grades.get(e)

The key function simply returns the value of the grade.

# from operator import itemgetter
# students.sort(key=lambda e: itemgetter(e)(grades))

This solution uses an anonymous function.

$ ./grades.py 
{'A+': 0, 'A': 1, 'A-': 2, 'B+': 3, 'B': 4, 'B-': 5, 'C+': 6, 'C': 7, 'C-': 8, 'D+': 9, 'D': 10}

This is the output.

Дополнительные заметки о сортировке в Python

Перед завершением статьи давайте рассмотрим, что говорит документация Python о сортировке:

Как видите, в официальной документации утверждается, что уже и так было доказано: немного эффективнее. Кроме того, в документации говорится о том, что зачастую намного удобнее.

Может возникнуть вопрос касательно того, являются ли обе техники стабильные. К счастью, в документации есть ответ и на это:

Также верно при использовании реверсивного параметра или применении реверсивной функции дважды.

Заключение

После проведения небольшого анализа мы доказали, что немного быстрее и потребляет на 24% меньше памяти. Однако, стоит иметь в виду, что имплементируется только для списков, в то время как принимает любые итерации. Кроме того, при использовании вы потеряете оригинальный список.

Python sort list of namedtuples

In the next example, we sort namedtuples.

namedtuple_sort.py

#!/usr/bin/env python3

from typing import NamedTuple


class City(NamedTuple):
    id: int
    name: str
    population: int


c1 = City(1, 'Bratislava', 432000)
c2 = City(2, 'Budapest', 1759000)
c3 = City(3, 'Prague', 1280000)
c4 = City(4, 'Warsaw', 1748000)
c5 = City(5, 'Los Angeles', 3971000)
c6 = City(6, 'Edinburgh', 464000)
c7 = City(7, 'Berlin', 3671000)

cities = 

cities.sort(key=lambda e: e.name)

for city in cities:
    print(city)

The namedtuple has three attributes: ,
, and . The example sorts the
namedtuples by their names.

cities.sort(key=lambda e: e.name)

The anonymous function returns the name property of the namedtuple.

$ ./namedtuple_sort.py 
City(id=7, name='Berlin', population=3671000)
City(id=1, name='Bratislava', population=432000)
City(id=2, name='Budapest', population=1759000)
City(id=6, name='Edinburgh', population=464000)
City(id=5, name='Los Angeles', population=3971000)
City(id=3, name='Prague', population=1280000)
City(id=4, name='Warsaw', population=1748000)

This is the output.

Sorting

In computer science, sorting is arranging elements in an ordered sequence. Over the years,
several algorithms were developed to perform sorting on data, including merge sort,
quick sort, selection sort, or bubble sort. (The other meaning of sorting is categorizing;
it is grouping elements with similar properties.)

The opposite of sorting, rearranging a sequence of elements in a random or meaningless order,
is called shuffling.

Data can be sorted alphabetically or numerically. The sort key specifies
the criteria used to perform the sort. It is possible to sort objects by multiple keys.
For instance, when sorting users, the names of the users could be used as primary sort key,
and their occupation as the secondary sort key.

Пример 2. Сортировка списка кортежей

Теперь давайте напишем программу для сортировки списка из трех кортежей, каждый из которых состоит из трех элементов.

Здесь мы используем три типа сортировки.

В первой сортирующей функции позиция сортировки устанавливается в 0. Таким образом мы отсортируем список по первым элементам кортежей.

Во второй сортирующей функции позиция сортировки – 1. Так мы отсортируем список по вторым элементам кортежей.

Чтобы отсортировать список по третьим элементам кортежей, установим позицию сортировки 2.

tuple_list = 
# Sort the list based on the first item of the tuple
sorted_list1 = sorted(tuple_list, key=lambda x: x)
# Print the first sorted list
print("The sorted list based on the first item:\n", sorted_list1)
# Sort the list based on the second item of the tuple
sorted_list2 = sorted(tuple_list, key=lambda x: x)
# Print the second sorted list
print("The sorted list based on the second item:\n", sorted_list2)
# Sort the list based on the third item of the tuple
sorted_list3 = sorted(tuple_list, key=lambda x: x)
# Print the third sorted list
print("The sorted list based on the third item:\n", sorted_list3)

Запустим наш код и получим три списка кортежей, отсортированных по указанным позициям.

The sorted list based on the first item:
 
The sorted list based on the second item:
 
The sorted list based on the third item:
 

Operator Module Functions

The key-function patterns shown above are very common, so Python provides convenience functions to make accessor functions easier and faster. The has itemgetter, attrgetter, and starting in Python 2.6 a methodcaller function.

Using those functions, the above examples become simpler and faster.

>>> from operator import itemgetter, attrgetter, methodcaller

>>> sorted(student_tuples, key=itemgetter(2))


>>> sorted(student_objects, key=attrgetter('age'))

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

>>> sorted(student_tuples, key=itemgetter(1,2))


>>> sorted(student_objects, key=attrgetter('grade', 'age'))

The third function from the operator module, methodcaller is used in the following example in which the weighted grade of each student is shown before sorting on it:

>>> 

>>> sorted(student_objects, key=methodcaller('weighted_grade'))

5.1.4. Анонимные функции¶

Python поддерживает синтаксис, позволяющий определять анонимные функции (лямбда-функции или лямбда-выражения):

lambda
lambda parameters expression
  • часть является необязательной, и если она присутствует, то обычно представляет собой простой список имен переменных, разделенных запятыми (позиционных аргументов);

  • выражение не может содержать условных инструкций или циклов (условные выражения — допустимы), а также не может содержать инструкцию ;

  • результатом лямбда-выражения является анонимная функция.

Когда лямбда-функция вызывается, она возвращает результат вычисления выражения .

Пример записи лямбда-функции приведен в Листинге 5.1.15.

Key Functions

Starting with Python 2.4, both list.sort() and sorted() added a key parameter to specify a function to be called on each list element prior to making comparisons.

For example, here’s a case-insensitive string comparison:

>>> sorted("This is a test string from Andrew".split(), key=str.lower)

The value of the key parameter should be a function that takes a single argument and returns a key to use for sorting purposes. This technique is fast because the key function is called exactly once for each input record.

A common pattern is to sort complex objects using some of the object’s indices as a key. For example:

>>> student_tuples = 
>>> sorted(student_tuples, key=lambda student: student)   # sort by age

The same technique works for objects with named attributes. For example:

>>> 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))
        def weighted_grade(self):
                return 'CBA'.index(self.grade) / float(self.age)

>>> student_objects = 
>>> sorted(student_objects, key=lambda student: student.age)   # sort by age

Встроенные функции сортировки на Python

Иногда полезно знать перечисленные выше алгоритмы, но в большинстве случаев разработчик, скорее всего, будет использовать функции сортировки, уже предоставленные в языке программирования.

Отсортировать содержимое списка можно с помощью стандартного метода sort():

Или можно использовать функцию sorted() для создания нового отсортированного списка, оставив входной список нетронутым:

Оба эти метода сортируют в порядке возрастания, но можно изменить порядок, установив для флага reverse значение True:

В отличие от других алгоритмов, обе функции в Python могут сортировать также списки кортежей и классов. Функция  может сортировать любую последовательность, которая включает списки, строки, кортежи, словари, наборы и пользовательские итераторы, которые вы можете создать.

Функции в Python реализуют алгоритм Tim Sort, основанный на сортировке слиянием и сортировке вставкой.

Гость форума
От: admin

Эта тема закрыта для публикации ответов.