Это по дизайну и намеренно. CPython временно «запрещает» доступ к списку, пока список сортируется на месте, поведение documented here:
CPython деталь реализации:Хотя список сортируется, то эффект попытки мутировать , или даже проверить, список не определен. Реализация C на Python делает список пустым на время и повышает значение ValueError, если он может обнаружить, что список был мутирован во время сортировки.
Вы можете проверить, что при печати A
внутри ключевой функции - вы получите пустой список:
In [2]: def key_function(x):
...: print(A, x)
...: return A.count(x)
...:
In [3]: A.sort(key=key_function)
([], 2)
([], 1)
([], 3)
([], 4)
([], 2)
([], 2)
([], 3)
Но, если вы сделаете это для sorted()
:
In [4]: sorted(A, key=key_function)
([2, 1, 3, 4, 2, 2, 3], 2)
([2, 1, 3, 4, 2, 2, 3], 1)
([2, 1, 3, 4, 2, 2, 3], 3)
([2, 1, 3, 4, 2, 2, 3], 4)
([2, 1, 3, 4, 2, 2, 3], 2)
([2, 1, 3, 4, 2, 2, 3], 2)
([2, 1, 3, 4, 2, 2, 3], 3)
Out[4]: [1, 4, 3, 3, 2, 2, 2]
Это также задокументировано внутри sort()
implementation:
/* The list is temporarily made empty, so that mutations performed
* by comparison functions can't affect the slice of memory we're
* sorting (allowing mutations during sorting is a core-dump
* factory, since ob_item may change).
*/.
Сторона примечания, вам не нужно «лямбда», например. 'A.sort (key = A.count)' –
Это возвращает количество событий для каждого элемента в A: '[A.count (element) для элемента в наборе (A)]' – UpSampler
Использование 'Counter' (' A.sort (key = collections.Counter (A) .get)) здесь будет более эффективным и будет работать как для сортировки, так и для сортировки. – Faibbus