0

Because I made my dict file with append list. I have the following dict file:

dict_1 = {'a':["1","2","d","d","d","1","2","2"], 
          'b':["1","2","e","e","5","5","5","6"]}

How do I sort the values by frequency within the list so I get output like:

dict_1 = {'a':["d","d","d","2","2","2","1","1"], 
          'b':["5","5","5","e","e","6","2","1"]}

The order doesn't matter for strings of the same frequency

I tried

result=[]
for k,v in dict_1.items():
    result.append(sorted(v, key = v.count,
                                reverse = True))

and got

[['2', 'd', 'd', 'd', '2', '2', '1', '1'],
 ['5', '5', '5', 'e', 'e', '1', '2', '6']]

Something is wrong with the "2" in the first list.

Thanks.

Iwishworldpeace
  • 478
  • 4
  • 12
  • Does this answer your question? [Sort list by frequency](https://stackoverflow.com/questions/25815377/sort-list-by-frequency) – P_A Sep 30 '21 at 07:08
  • 1
    The reason it happens is because e.g. `'2'` and `'d'` have the same number of appearances (3) within the first list, and therefore when sorting that list, there is no reason to put the individual `'2'` and `'d'` in any particular order - thus they aren't kept separate from each other. The trick to finding help with this problem is to understand that you aren't simply trying to sort, but also partition values - group like values together, sort the groups by frequency, and emit the corresponding output. – Karl Knechtel Sep 30 '21 at 07:42
  • 1
    As an aside, please read https://stackoverflow.com/help/minimal-reproducible-example. Evidently, the *difficulty* here is *not* "how do I apply this custom sorting to each value in a dict?", therefore you should *not include* that part of the code when asking the question. Instead, ask specifically about sorting a single list. Clearly, once you know how to do that, you can solve the entire problem. – Karl Knechtel Sep 30 '21 at 07:43

2 Answers2

3

One way using collections.Counter with dict comprehension:

from collections import Counter

cnts = {k: Counter(v) for k, v in dict_1.items()}

Or without Counter, using list.count:

cnts = {k: {i: v.count(i) for i in set(v)} for k, v in dict_1.items()}

Then do sort:

{k: sorted(v, key=lambda x: (cnts[k][x], x), reverse=True) for k, v in dict_1.items()}

Output:

{'a': ['d', 'd', 'd', '2', '2', '2', '1', '1'],
 'b': ['5', '5', '5', 'e', 'e', '6', '2', '1']}

Note:

key for sorted returns tuple of (count, itself) so that same items remain grouped.

Chris
  • 29,127
  • 3
  • 28
  • 51
0

Here is a way to do it without collections module in python.

dict_1 = {'a':["1","2","d","d","d","1","2","2"], 
          'b':["1","2","e","e","5","5","5","6"]}

for items in dict_1: # looping through the dictionary to get every key value pair in the dictionary

    l = dict_1.get(items) # getting the value of every key value pair in the dictionary. Here "l" is short for "list"
    print(sorted(l, key=l.count, reverse=True)) # sorting it according to frequency of the element in the list.

Output:

['2', 'd', 'd', 'd', '2', '2', '1', '1']
['5', '5', '5', 'e', 'e', '1', '2', '6']

You can read more about sorted() from this link

Nishil Sheth
  • 155
  • 1
  • 10