Я прочитал учебник 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]
x
в helper(x)
?Клавиша сортировки - это функция, которая генерирует значения для входа для сортировки. Приказ, введенный после сортировки значений 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]
Это делает следующее:
Ключевой параметр в sort() требует функции, и он применяет эту функцию к каждому элементу списка, который сортируется. В вашем примере каждый элемент значений передается в helper(), который затем проверяет, находится ли этот элемент в группе. Сортировка затем сравнивает список кортежей, и кортежи с первым элементом из 0 всегда будут поступать перед кортежами с первым элементом из 1.
Источник: https://wiki.python.org/moin/HowTo/Sorting#Key_Functions
Резюме:
Поскольку такая функция есть, имеет аргумент для элемента, btw это эквивалентно lambda x:..
Может быть, вы более знакомы с этим, поэтому вы сортируете значения этой функцией, в основном прямой helper
в сортировке эквивалентен lambda x: helper(x)
может быть более знакомым, Btw это не кортеж, это набор, потому что он содержит фигурные скобки и не содержит двоеточий
Поэтому, чтобы ответить на ваши вопросы один за другим:
1) Где передается фактическое значение параметра x в хелпере (x)?
Он применяет этот метод к каждой функции и, как вам известно выше, эквивалентно
lambda x: helper(x)
.2) Я понимаю, что Python сначала сравнивает индекс 0-to-0, затем индекс 1-к-1 и т.д. В кортеже; но не совсем уверен, как в этом случае используется сравниваемый исходный кортеж.
Ну, потому что вы возвращаете значение в
helper
функции, чтобы как-то сортировать.