代码之家  ›  专栏  ›  技术社区  ›  gw0

Python sorted()键函数怪异

  •  2
  • gw0  · 技术社区  · 14 年前

    当我调试一些不合逻辑的行为时,在Python2.5中出现了以下奇怪的情况 排序()

    >>> aa = [10, 5, 20]
    >>> sorted(range(len(aa)))
    [0, 1, 2]
    sorted(range(len(aa)), key=lambda a: aa[a])
    [1, 0, 2]
    sorted(range(len(aa)), key=lambda a: -aa[a])
    [2, 0, 1]
    

    前两个呼叫按预期工作,但最后一个是imho 错误的

    在试图找出问题根源的进一步实验之后,我得出了这样的结论(不使用lambda或否定运算,但在其他方面是相同的问题):

    >>> bb = [-10, -5, -20]
    >>> sorted([0, 1, 2], key=bb.__getitem__)
    [2, 0, 1]
    

    即使像下面这样的事情也不起作用,表明双重否定又起作用了:

    >>> bb = [-10, -5, -20]
    >>> def fun(i):
    ...    return bb[i]
    >>> sorted([0, 1, 2], key=fun)
    [2, 0, 1]
    >>> def fun2(i):
    ...     return -bb[i]
    >>> sorted([0, 1, 2], key=fun2)
    [1, 0, 2]
    

    我是疯了还是哪里出了问题?或者为什么Python 3.x没有 化学机械抛光

    3 回复  |  直到 14 年前
        1
  •  8
  •   unutbu    14 年前

    key函数返回的值充当被排序值的代理。 所以当你说

    sorted(range(len(aa)), key=lambda a: -aa[a])
    

    range(len(aa) ),即 [0, 1, 2] ,但使用值 -aa[0], -aa[1], -aa[2]

    range(len(aa))   0   1   2    <-- values
    aa[a]           10   5  20
    -aa[a]         -10  -5 -20    <-- proxy values
    

    从-20开始,或 -aa[2] ,是最小的代理值,其关联值为2 成为排序结果中的第一个元素。

    从-10开始,或 -aa[0]

    最后-5,或者 -aa[1] 是最后一个值,因此1是排序结果中的最后一个数字。

    sorted(range(len(aa)), key=lambda a: -aa[a]) 等于 [2, 0, 1] .

        2
  •  1
  •   Richard Fearn    14 年前

    错误的 ! 应该是:[1,2,0]

    lambda a: aa[a] 它按大小顺序为元素提供索引。

    在最后一个例子中,关键是 lambda a: -aa[a] . 由于取反,这将为您提供 减少 尺寸顺序。

    所以最后的结果应该是 [2, 0, 1] -它与 [1, 0, 2]

    在这个例子中

    >>> bb = [-10, -5, -20]
    >>> sorted([0, 1, 2], key=bb.__getitem__)
    [2, 0, 1]
    

    你得到的元素的索引是按大小顺序递增的- [2,0,1] 对应于 [-20, -10, -5] .

    在最后两个示例中,您再次按大小顺序获取元素的索引( ),或减小大小顺序( [1,0,2] ).

        3
  •  0
  •   John La Rooy    14 年前

    >>> bb = [-10, -5, -20]
    >>> sorted([0, 1, 2], key=bb.__getitem__)
    [2, 0, 1]  ==> corresponds to bb.__getitem__ of [-20, -10, -5]