Python sorted () ключевая функция странность - PullRequest
2 голосов
/ 07 ноября 2010

Пока я отлаживал какое-то нелогичное поведение, я столкнулся со следующей странностью в Python 2.5 sorted () вызовы функций:

>>> 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 просто неправильно ! Должно быть: [1, 2, 0].

После дальнейших экспериментов по попытке найти корень проблемы я пришел к этому (не использует лямбду или операцию отрицания, но в остальном это та же проблема):

>>> 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 не имеет аргумента cmp , который работал нормально (совместимость - причина, по которой я его не использую)?

Ответы [ 3 ]

8 голосов
/ 07 ноября 2010

Значение, возвращаемое ключевой функцией, действует как прокси для сортируемых значений.Поэтому, когда вы говорите

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] является следующим наименьшим, его ассоциированное значение 0 становитсявторой элемент в отсортированном результате.

Наконец, -5 или -aa[1] - последнее значение, поэтому 1 - последнее число в отсортированном результате.

Таким образом, sorted(range(len(aa)), key=lambda a: -aa[a]) равно[2, 0, 1].

Правильный ответ Python.

1 голос
/ 07 ноября 2010

последний имхо просто неправильно !Это должно быть: [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].

В ваших последних двух примерахВы снова получаете индексы для элементов в порядке увеличения размера ([2, 0, 1]) или уменьшения порядка размера ([1, 0, 2]).

0 голосов
/ 07 ноября 2010

Это имеет смысл для меня

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