2

A given array is to be sorted on the basis of the frequency of occurrence of its elements.

I tried using key=arr.count (arr is the name of the list I want to sort). It works for some inputs. I also tried using the collections.Counter() class object, it behaved similarly to how arr.count did.

>>> arr = [6, 4, 6, 4, 4, 6, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 1, 7, 7, 7, 2, 2, 2, 7, 1, 7, 1, 2, 1, 2, 7, 1, 1, 7, 2, 1, 2]
>>> sorted(arr, key=arr.count)
[6, 4, 6, 4, 4, 6, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 1, 7, 7, 7, 2, 2, 2, 7, 1, 7, 1, 2, 1, 2, 7, 1, 1, 7, 2, 1, 2]
>>> sorted(arr, key=counts.get)
[6, 4, 6, 4, 4, 6, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 1, 7, 7, 7, 2, 2, 2, 7, 1, 7, 1, 2, 1, 2, 7, 1, 1, 7, 2, 1, 2]

Expected output is:

1 1 1 1 1 1 1 2 2 2 2 2 2 2 7 7 7 7 7 7 7 3 3 3 3 3 3 5 5 5 5 4 4 4 6 6 6

Not sure what I am doing wrong here.

Georgy
  • 6,348
  • 7
  • 46
  • 58
  • 1
    4 and 6 have the same count, so your output fits your criteria. You need an additional criteria if you want to separate items of same count. – MisterMiyagi Jun 08 '19 at 07:58
  • 2
    Using arr.count in this way is an incredibly inefficient way of sorting by frequency `O(n**2*log(n))`. Using collections.Counter way would've been a lot more efficient and more clearer as well. – Lie Ryan Jun 08 '19 at 08:25

2 Answers2

2

Use a tuple to sort first by frequency and then by value, for inverting the ordering you can use - (so smallest numbers comes first), and then since you want the biggest count first use reverse:

sorted(arr, key=lambda x: (arr.count(x), -x), reverse=True)

Output:

[1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 4, 4, 4, 6, 6, 6]
Netwave
  • 23,907
  • 4
  • 31
  • 58
1

I think the problem is that some entries have the same frequency, e.g.:

arr.count(1) == arr.count(2) == arr.count(7)

To make sure that these entries remain grouped, you have to sort not only by counts, but also by value:

counts = collections.Counter(arr)
sorted(arr, key=lambda x: (counts[x], x), reverse=True)

Output: [7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 6, 6, 6, 4, 4, 4]

Nikolai
  • 49
  • 8