Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort a list by the number of occurrences of the elements in the list [duplicate]

Tags:

I want to sort a list by the number of occurrences of the elements in the list.
When I use this form:

A=[2,1,3,4,2,2,3] A.sort(key=lambda x:A.count(x))   print(A) 

the result is not what I want: [2, 1, 3, 4, 2, 2, 3].
But, when I write like it using sorted:

B=sorted(A,key=lambda x:A.count(x)) print(B) 

the result is right: [1, 4, 3, 3, 2, 2, 2].
what's the reason for this behavior?

like image 513
hukaixuan Avatar asked Feb 03 '17 14:02

hukaixuan


People also ask

How do you count the number of repeated elements in a list?

Method 2: Count occurrences of an element in a list Using count() The idea is to use the list method count() to count the number of occurrences.

How do you sort duplicates in Python list?

Method #1 : Using count() + set() + sorted() The sorted function can be used to sort the elements as desired, the frequency can be computed using the count function and removal of duplicates can be handled using the set function.

Can list contain duplicate elements?

As we know that list can hold duplicate values but will not update if it contains duplicate values.


1 Answers

This is by design and intentional. CPython temporarily "disallows" access to the list while the list is being sorted in place, the behavior is documented here:

CPython implementation detail: While a list is being sorted, the effect of attempting to mutate, or even inspect, the list is undefined. The C implementation of Python makes the list appear empty for the duration, and raises ValueError if it can detect that the list has been mutated during a sort.

You can inspect that by printing A inside the key function - you'll get an empty list:

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) 

But, if you do that for 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] 

It is also documented inside the 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).  */. 
like image 139
alecxe Avatar answered Sep 21 '22 21:09

alecxe