5

在处理 Google Python 类的问题时,我使用 Stack overflow 中的 2-3 个示例制定了以下结果-

def sort_last(tuples):
    return [b for a,b in sorted((tup[1], tup) for tup in tuples)]

print sort_last([(1, 3), (3, 2), (2, 1)])

我昨天学习了列表理解,所以对列表理解有一点了解,但我对这个解决方案的整体工作方式感到困惑。请帮助我理解这一点(函数中的第二行)。

4

4 回答 4

6

这种模式称为装饰-排序-不装饰。

  1. 你把每一个都(1, 3)变成(3, (1, 3)),将每一个包装tuple在一个新的元组中,并首先使用你想要排序的项目。
  2. 您排序,外部tuple确保原始中的第二个项目tuple首先排序。
  3. 您在保持列表顺序的同时返回从(3, (1, 3))到。(1, 3)

在 Python 中,显式装饰几乎总是不必要的。相反,使用 的key参数sorted

sorted(list_of_tuples, key=lambda tup: tup[1]) # or key=operator.itemgetter(1)

或者,如果您想对 的反转版本进行排序tuple,无论其长度如何:

sorted(list_of_tuples, key=lambda tup: tup[::-1]) 
                              # or key=operator.itemgetter(slice(None, None, -1))
于 2012-04-18T16:46:53.303 回答
3

让我们分解一下:

在 :[(tup[1],tup) for tup in tuples]

出去:[(3, (1, 3)), (2, (3, 2)), (1, (2, 1))]

所以我们刚刚创建了新的元组,它的第一个值是内部元组的最后一个值 - 这样它就按“元组”中每个元组的第二个值排序。

现在我们对返回的列表进行排序:

在:sorted([(3, (1, 3)), (2, (3, 2)), (1, (2, 1))])

出去:[(1, (2, 1)), (2, (3, 2)), (3, (1, 3))]

所以我们现在有我们的列表按每个元组的第二个值排序。剩下的就是提取原始元组,这是通过从 for 循环中仅获取 b 来完成的。

列表推导迭代给定列表(sorted([...]在本例中)并按顺序返回提取的值。

于 2012-04-18T16:54:41.340 回答
2

您的示例通过创建一个新列表来工作,其中索引处的元素1后跟列表中每个元组的原始元组。例如。(3,(1,3))对于第一个元素。sorted 函数从 index 开始按每个元素0排序,因此列表按第二项排序。然后该函数遍历新列表中的每个项目,并返回原始元组。

另一种方法是使用keysorted 函数中的参数,该参数根据key. 在这种情况下,您希望 成为keyindex 处每个元组中的项目1

>>> from operator import itemgetter
>>> sorted([(1, 3), (3, 2), (2, 1)],key=itemgetter(1))
于 2012-04-18T16:45:25.630 回答
0

请参考接受的答案.. + 这是一个更好的可视化示例,

key是一个函数,将被调用以转换集合的项目以进行比较..类似于compareToJava 中的方法。

传递给 key 的参数必须是可调用的。在这里,使用lambda创建了一个匿名函数(它是可调用的)。
lambda 的语法是单词 lambda,后跟一个可迭代的名称,然后是一个代码块。

在下面的示例中,我们正在对包含特定事件和演员姓名的信息 abt 时间的元组列表进行排序。

我们按事件发生的时间对这个列表进行排序——这是元组的第 0 个元素。

为准备好的球员一号球迷大喊!=)

>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')]
>>> gunters.sort(key=lambda tup: tup[0])
>>> print gunters
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')]

注意 -s.sort([cmp[, key[, reverse]]]) 对 s 的项目进行就地排序

于 2017-05-25T18:30:21.047 回答