【问题标题】:Frustrated with Python's sorted Built-in (with range and lambda as key)对 Python 的 sorted Built-in 感到沮丧(以 range 和 lambda 作为键)
【发布时间】:2018-01-31 04:19:24
【问题描述】:

我遇到了一些对我来说毫无意义的事情。请参阅 sortedrangelambda 的这种用法:

sorted(range(-5, 6), key=lambda x: x * x)

在 Python shell 中输出:

[0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5]

现在,为了我的一生,我不明白这个!我一直在玩sortedlambdarange,这没有任何意义。例如,如果你在 for 循环中运行 range 位,你会得到这样的结果:

>>> for i in range(-5, 6):
...     print(i)
-5
-4
...
0
...
4
5

还有lambda 位:

>>> (lambda x: x * x)(-5)
25

但是把它们放在一起......我不明白如何以这种方式使用key 使顺序与符号无关。

但这对我来说很有意义:

>>> sorted(range(-5, 6), key=lambda x: abs(x))
[0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5]

有人可以解释一下吗?

【问题讨论】:

  • 就排序键而言,对数字求平方并取其绝对值是一回事。你没有得到什么?因为对数字求平方会使每个(实数)数字都是正数。从这个意义上说,它与取绝对值具有相同的效果。
  • 为什么你认为x^2abs(x) 的排序会不同?
  • n^2 == (-n)^2
  • 我怀疑 lambda 确实会分散注意力。
  • @nicorellius 很好,对于每个实数 x,(x)^2 == (-x)^2。想想抛物线图,它是 y 轴上的镜像......或者也许:(-x)^2 == (-x)*(-x) == (-1*x)(- 1*x) == (-1)(-1)(x)(x) == (1)(x)(x) == (x)^2 ...这实际上更像是一个数学问题。再次,只是look at the graph

标签: python python-3.x sorting lambda


【解决方案1】:

让我们一步一步来:

  • 您要排序的序列是range(-5, 6),即[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]

  • 这个序列的元素及其对应的键是:

      x | x * x
    ----|-------
     -5 | 25
     -4 | 16
     -3 |  9
     -2 |  4
     -1 |  1
      0 |  0
      1 |  1
      2 |  4
      3 |  9
      4 | 16
      5 | 25
    
  • 现在让我们按键排序:

             x | x * x
    -----------|-------
             0 |  0
      -1 and 1 |  1
      -2 and 2 |  4
      -3 and 3 |  9
      -4 and 4 | 16
      -5 and 5 | 25
    

    这意味着sorted()的输出将是0,然后是-11,然后是-22,等等sorted() performs a stable sort,所以任何具有相同键的输入元素将按照它们在输入中出现的顺序输出;因为负数出现在range(-5, 6) 的正数之前,这意味着sorted() 将在1 之前输出-1-22 之前输出,等等。

  • 因此,最终输出为[0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5]

【讨论】:

  • 这很棒。我找到的文档中的一个关键行是:The value of the key parameter should be a function that takes a single argument and returns a key to use for sorting purposes. 所以在某种程度上,它就像创建一个有序字典,其中的键根据函数 (x*x) 和 @987654344 的返回值排序@return 仅将此字典中按顺序排列的值作为列表返回。这对我来说很有意义。
  • 感谢您的回答...我开始了解它是如何工作的。对于你的第二个项目符号,如果你使用x * x 列作为排序顺序,从中间或零开始,你会得到0, 1, 1, . . . 25, 25(就像上面评论的@Sanju)。如果将此应用于range(-5, 6) 中的列,则会得到0, -1 or 1, -2 or 2, . . . -5 or 5。从这里开始,这是 Python 遵循的规则问题,例如,sorted()1 之前输出-1,你就完成了!谢谢!这帮助很大。
  • @Idlehands 或者,实际上,考虑对(keyfunc(x), x) 形式的对列表进行排序可能会更好,即“施瓦茨变换”en.wikipedia.org/wiki/Schwartzian_transform
  • @nicorellius -1 出现在 1 之前的原因是因为 python 的排序算法(我相信是 tim sort)是stable。也就是说,两个其他相等的元素(根据键)将保持它们的顺序。因此,-1 出现在 1 之前,因为它们具有相同的键,而 -1 在原始输入中出现在 1 之前
猜你喜欢
  • 2016-07-07
  • 1970-01-01
  • 2011-05-29
  • 2011-01-26
  • 1970-01-01
  • 2014-07-21
  • 2013-06-06
  • 1970-01-01
相关资源
最近更新 更多