在闭包功能的帮助下在python中排序优先级



我读了一本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. 传递xhelper(x)参数的实际值在哪里?
  2. 我知道 Python 首先比较元组中的 0 到 0 索引,然后是 1 到 1 索引等;但不太确定在这种情况下如何使用返回的元组进行比较。

排序键是生成备用值供您排序的函数。对替身值进行排序后强加的顺序将强加于原件。排序键对列表的每个元素应用一次。因此,而不是按照规定的顺序进行分类

[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}的元素,这将始终在元素"标记"为 1 之前排序。这是因为首先比较"标签",即每个元组的第一个元素。

对键进行排序时,实际值将按相同的顺序放置。

例如,较新版本的Python根本不支持比较器,这与C和Java不同:它根本不必要。正确构造的键函数可以完成比较器可以做的所有事情,并且每个元素只需要评估一次,而不是多次。当然,键本身仍然需要相同的次数比较。

排序键还允许您对没有自然排序的元素列表进行排序(不支持像<这样的比较运算符(。使用正确的键,您甚至可以对包含通常无法相互比较的不同类型的元素的列表进行排序。

附带说明一下,布尔值是 Python 中整数的一个特殊子类:False == 0True == 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. 从原始序列中提取每个排序元素对应的元素,并返回结果。

sort(( 中的键参数需要一个函数,它将该函数应用于正在排序的每个列表元素。在您的示例中,值的每个元素都传递到 helper(( 中,然后 helper(( 检查该元素是否在组中。然后排序比较元组列表,第一个元素为 0 的元组总是在第一个元素为 1 的元组之前。

源: https://wiki.python.org/moin/HowTo/Sorting#Key_Functions

总结:

因为像这样的函数,对项目有一个参数,顺便说一句,它相当于lambda x: ..也许你更熟悉它,所以你按该函数对值进行排序,基本上直接helper排序相当于lambda x: helper(x)可能更熟悉,顺便说一句,它不是一个元组,它是一个集合,因为它包含大括号并且不包含冒号

所以要一一回答你的问题:

1( 帮助程序(x(中x参数的实际值在哪里传递?

它将该方法应用于每个函数,正如您从上面所知道的,相当于lambda x: helper(x).

2(我知道Python首先比较0到0索引,然后在元组中比较1到1索引等;但不太确定在这种情况下如何使用返回的元组进行比较。

好吧,因为你在helper函数中返回值,所以这就是它的排序方式。

最新更新