0

I know there are many solutions (How do I sort a dictionary by value?) to sorting a dictionary by values. However, most of those predate python 3.7's changes to dictionary.

I am also aware of Fastest way to sort a python 3.7+ dictionary, which seems close to the answer I need.

I have a large dictionary of keys that are ints and values that are sets of strings.

I want to create a new dictionary that is sorted by the length of the set of each value.

Dictionary:

dict1={
'12':{'sym1', 'sym2'},
'13':{'sym1', 'sym4', 'sym5', 'sym6'},
'14':{'sym1', 'sym3'},
'15':{'sym2'},
'16':{'sym2'},
'17':{'sym2'},
'18':{'sym3', 'sym89', 'sym34', 'sym5', 'sym88'}
}

New sorted dictionary:

>>sorted_dict1

{
'18':{'sym3', 'sym89', 'sym34', 'sym5', 'sym88'},
'13':{'sym1', 'sym4', 'sym5', 'sym6'},
'12':{'sym1', 'sym2'},
'14':{'sym1', 'sym3'},
'15':{'sym2'},
'16':{'sym2'},
'17':{'sym2'}
}
Britt
  • 539
  • 1
  • 7
  • 21
  • `sorted()` has a `key` parameter, that is used to specify the way items are sorted. You might be able to set it to sort by length. – Legorooj Jun 24 '19 at 17:39

1 Answers1

0

I think this is a very slow way to do this, but here goes:

  1. create a dictionary that has the same keys, and the value is the length of the set of the key

from operator import itemgetter

dict1={
'12':{'sym1', 'sym2'},
'13':{'sym1', 'sym4', 'sym5', 'sym6'},
'14':{'sym1', 'sym3'},
'15':{'sym2'},
'16':{'sym2'},
'17':{'sym2'},
'18':{'sym3', 'sym89', 'sym34', 'sym5', 'sym88'}
}

dict1_len ={}
for k,v in dict1.items():
    dict1_len.update({k:len(v)})
  1. Sort dict1_len by the value numbers in reverse (descending).
sorted_dict1_len = {k: v for k,v in sorted(dict1_len.items(), key=itemgetter(1), reverse=True)}
  1. using the keys in the order given by sorted_dict1_len, add the key and the values of that key as given by the original dict1 to sorted_dict1.
sorted_dict1 = {}

for k in sorted_dict1_len.keys():
    print(k)
    sorted_dict1.update({k:dict1.get(k)})

Edit: improved answer

from operator import itemgetter

dict1={
'12':{'sym1', 'sym2'},
'13':{'sym1', 'sym4', 'sym5', 'sym6'},
'14':{'sym1', 'sym3'},
'15':{'sym2'},
'16':{'sym2'},
'17':{'sym2'},
'18':{'sym3', 'sym89', 'sym34', 'sym5', 'sym88'}
}

def len_val(tup):
    return len(tup[1]) # length of the value i.e. elements in set

dict2 = sorted(dict1.items(), key=len_val, reverse=True)

print(dict2)

returns

[('18', {'sym88', 'sym5', 'sym89', 'sym3', 'sym34'}), ('13', {'sym1', 'sym5', 'sym6', 'sym4'}), ('12', {'sym1', 'sym2'}), ('14', {'sym3', 'sym1'}), ('15', {'sym2'}), ('16', {'sym2'}), ('17', {'sym2'})]
Britt
  • 539
  • 1
  • 7
  • 21