Приоритет сортировки в python с помощью функции закрытия

1

Я прочитал учебник Python, который имеет следующую функцию закрытия, используемую в сочетании с сортировкой. Предполагается, что эта функция сортировки выделяет приоритеты номеров, которые относятся к набору специальных group, а затем сортирует остаток:

def sort_priority(values, group):
    def helper(x):
        if x in group:
            return (0, x)
        return (1, x)
    values.sort(key=helper)

numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = {2, 3, 5, 7}
sort_priority(numbers, group)
print(numbers)

Выход:

[2, 3, 5, 7, 1, 4, 6, 8]
  1. Где передается фактическое значение параметра x в helper(x)?
  2. Я понимаю, что Python сначала сравнивает индекс 0-к-0, затем индекс 1-к-1 и т.д. В кортеже; но не совсем уверен, как в этом случае используется сравниваемый исходный кортеж.
Теги:

3 ответа

1
Лучший ответ

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

[8, 3, 1, 2, 5, 4, 7, 6]

вы сортируете в порядке, предусмотренном

[helper(8), helper(3), helper(1), helper(2), helper(5), helper(4), helper(7), helper(6)]

helper называется один раз для каждого элемента списка, эффективно, как если бы вы делали

[helper(x) for x in values]

Теперь вы разбираетесь в порядке,

[(1, 8), (0, 3), (1, 1), (0, 2), (0, 5), (1, 4), (0, 7), (1, 6)]

Создание элементов в кортеж позволяет вам "пометить" элементы набора {2, 3, 5, 7} нулями, которые всегда будут сортироваться до того, как элемент "помечен" одним. Это потому, что сначала сравнивается "тег", который является первым элементом каждого кортежа.

Когда ключи сортируются, фактические значения помещаются в том же порядке.

Более новые версии Python не поддерживают компараторы вообще, в отличие от C и Java, например: это просто не нужно. Правильно сконструированная ключевая функция может делать все, что может сделать компаратор, и ее нужно оценивать только один раз за элемент, а не несколько раз. Конечно, сами ключи по-прежнему нужно сравнивать столько же раз.

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

На боковой ноте булевы являются специальным подклассом целых чисел в Python: False == 0 и True == 1. Поскольку это теги, которые вы используете для разделения ключей на категории, вы можете переписать helper чтобы избежать условного:

def helper(x):
    return (x not in group, x)

аппендикс

Чтобы помочь вам лучше понять сортировку ключей, здесь реализована реализация, которая делает то же самое, что и передача ключа методу sort, но не на месте (что больше похоже на sorted встроенный):

def my_sorted(iterable, key):
    iterable = list(iterable)
    elements = [(key, index) for index, key in enumerate(iterable)]
    elements.sort()
    return [iterable[index] for _, index in elements]

Это делает следующее:

  1. Преобразуйте вход во что-то, что можно проиндексировать (последовательность), так как не все итерации могут быть проиндексированы из коробки.
  2. Вычислить ключ каждого элемента и индекс в исходном списке. Это позволит вам извлечь элементы в правильный порядок после сортировки ключей. Он также обеспечивает дополнительный уровень стабильности для сортировки. По умолчанию Python Timsort уже стабилен, но любые связи между ключами будут разбиты индексом.
  3. Сортировка списка ключей и индексов по ключу.
  4. Извлеките элемент, соответствующий каждому отсортированному элементу из исходной последовательности, и верните результат.
1

Ключевой параметр в sort() требует функции, и он применяет эту функцию к каждому элементу списка, который сортируется. В вашем примере каждый элемент значений передается в helper(), который затем проверяет, находится ли этот элемент в группе. Сортировка затем сравнивает список кортежей, и кортежи с первым элементом из 0 всегда будут поступать перед кортежами с первым элементом из 1.

Источник: https://wiki.python.org/moin/HowTo/Sorting#Key_Functions

0

Резюме:

Поскольку такая функция есть, имеет аргумент для элемента, btw это эквивалентно lambda x:.. Может быть, вы более знакомы с этим, поэтому вы сортируете значения этой функцией, в основном прямой helper в сортировке эквивалентен lambda x: helper(x) может быть более знакомым, Btw это не кортеж, это набор, потому что он содержит фигурные скобки и не содержит двоеточий

Поэтому, чтобы ответить на ваши вопросы один за другим:

1) Где передается фактическое значение параметра x в хелпере (x)?

Он применяет этот метод к каждой функции и, как вам известно выше, эквивалентно lambda x: helper(x).

2) Я понимаю, что Python сначала сравнивает индекс 0-to-0, затем индекс 1-к-1 и т.д. В кортеже; но не совсем уверен, как в этом случае используется сравниваемый исходный кортеж.

Ну, потому что вы возвращаете значение в helper функции, чтобы как-то сортировать.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню