【问题标题】:How does the key argument in python's sorted function work?python 的 sorted 函数中的 key 参数是如何工作的?
【发布时间】:2015-11-21 04:13:27
【问题描述】:

说我有

votes = {'Charlie': 20, 'Able': 10, 'Baker': 20, 'Dog': 15}

我明白了

print(sorted(votes.items(), key=lambda x: x[1]))

会导致

[('Able', 10), ('Dog', 15), ('Baker', 20), ('Charlie', 20)]

但是这是如何工作的呢?

【问题讨论】:

  • 我明白了,谢谢,那么如果我更改密钥以返回一个元组呢?那里发生了什么? key = lambda x: (-x[1],x[0])
  • 这将按元组 (-value, key) 排序。它最终会按值从大到小排序,并打破与键的联系。结果将是[('Baker', 20), ('Charlie', 20), ('Dog', 15), ('Able', 10)]
  • 哦,好吧,如果排序忽略了 x[0] 在元组中的关键方面的目的是什么?我想我的意思是,我为什么要在 lambda 中返回一个元组?
  • x[0] 不会被忽略;它用于与元组中的第一项断开联系。这就是为什么('Baker', 20) 总是出现在('Charlie', 20) 之前的原因
  • 在对元组进行排序时,Python首先按第一个值排序。然后,如果有任何关系(即两个或多个元组具有相同的第一个值),它按第二个值排序,如果第二个值有任何关系,则按第三个值排序,等等。把它想象成按字母顺序排序单词命令。首先你按第一个字母排序;如果有任何关系,则按第二个字母排序;你继续前进,直到没有更多的联系,或者你的信件用完了。

标签: python sorting dictionary


【解决方案1】:

您传递给key 的函数会得到每个正在排序的项目,并返回一个Python 可以用来排序的“键”。所以,如果你想通过字符串的 reverse 对字符串列表进行排序,你可以这样做:

list_of_strings.sort(key=lambda s: s[::-1])

这使您可以指定每个项目的排序依据,而无需更改项目。这样,您不必构建一个反转字符串列表,对其进行排序,然后将它们反转回来。

# DON'T do this

data = ['abc', 'def', 'ghi', 'jkl']
reversed_data = [s[::-1] for s in data]
reversed_data.sort()
data = [s[::-1] for s in reversed_data]

# Do this

data.sort(key=lambda s: s[::-1])

在您的情况下,代码按元组中的 second 项对每个项目进行排序,而通常它最初会按元组中的第一项排序,然后与第二项中断联系。

【讨论】:

    【解决方案2】:

    key 是一个函数,将被调用以在比较集合的项目之前对其进行转换。传递给 key 的参数必须是可调用的。

    使用 lambda 创建一个匿名函数(可调用)。在 sorted 的情况下,callable 只接受一个参数。 Python 的 lambda 非常简单。它真的只能做和回报一件事。

    【讨论】:

      【解决方案3】:
      >>> votes = {'Charlie': 20, 'Able': 10, 'Baker': 20, 'Dog': 15}
      

      如果我们在上面的votes 字典上应用.items(),我们会得到:

      >>> votes_items=votes.items()
      >>> votes_items
      [('Charlie', 20), ('Baker', 20), ('Able', 10), ('Dog', 15)]
      #a list of tuples, each tuple having two items indexed 0 and 1
      

      对于每个元组,第一个索引 [0] 是字符串 ('Charlie','Able','Baker','Dog'),第二个索引 [1] 是整数 (20,10,20,15)。

      print(sorted(votes.items(), key = lambda x: x[1])) 指示 python 使用每个元组的第二个索引[1](整数)对votes 中的项目(tuples) 进行排序,作为排序的基础。

      Python 比较每个元组中的每个整数并返回一个列表,该列表使用每个元组的整数作为key 以升序排列每个元组(这可以用reverse=True 参数反转)以确定元组的排名,

      如果键中存在平局,则项目按照它们在字典中的原始顺序排列。 (所以('Charlie', 20)('Baker', 20) 之前,因为键上有20==20 领带,但是(在原始votes 字典中,'Charlie', 20)('Baker', 20) 之前)。

      那么输出是:

       [('Able', 10), ('Dog', 15), ('Charlie', 20), ('Baker', 20)]
      

      我希望这会让它更容易理解。

      【讨论】:

        【解决方案4】:

        key参数取一个函数作为其值,在排序前应用于每个元素,从而根据该函数的输出对元素进行排序。

        例如,如果您想根据字符串的长度对字符串列表进行排序,您可以执行以下操作:

            list = ['aaaaaa', 'bb', 'ccc', 'd']
            sorted(list, key=len)
        
            # ['d', 'bb', 'ccc', 'aaaaaa']
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-12-09
          • 1970-01-01
          • 2018-08-07
          • 2018-01-04
          • 2012-02-04
          • 2018-07-07
          相关资源
          最近更新 更多