-2

I need to sort a list which is a value of dictionaries by using a function with less computation cost. I would not able to share the original code, so please help me with the following example.

I tried with the standard approach, I parsed the values, used the intermediate list to sort and stored it in the new dictionary which is highly computation intensive. I am trying to streamline it, for that, I am expecting any suggestions or ways to incorporate.

Input

a= {'a':1, 'b': [2,8,4,3], 'c':['c',5,7,'a',6]}

Output

a= {'a':1, 'b': [2,3,4,8], 'c':['a','c',5,6,7]}

  • 3
    What have you tried already? – DeepSpace Oct 18 '18 at 11:47
  • I tried with the standard approach, I parsed the values, used the intermediate list to sort and stored it in the new dictionary which is highly computation intensive. I am trying to streamline it, for that, I am expecting any suggestions or ways to incorporate. – Ranjith Udayakumar Oct 18 '18 at 11:52
  • 1
    Please check [\[SO\]: How to create a Minimal, Complete, and Verifiable example (mcve)](https://stackoverflow.com/help/mcve) for details on how a question should look like. – CristiFati Oct 18 '18 at 11:53
  • 1
    @PatrickArtner, Actually the list contains string and numbers, a and c are representing strings... I edited it, thanks for the point out. – Ranjith Udayakumar Oct 18 '18 at 11:59

2 Answers2

1

You do not need to sort the dict, you need to sort all values that are lists inside your dict. You do not need to create any new objects at all:

a= {'a':1, 'b': [2,8,4,3], 'c':['c',5,7,'a',6]} # changed c and a to be strings

for e in a:
    if isinstance(a[e],list):
        a[e].sort()         # inplace sort the lists

print(a)

Output:

{'a': 1, 'c': [5, 6, 7, 'a', 'c'], 'b': [2, 3, 4, 8]}

This does not create new dicts nor does it create new lists - it simply sorts the list in-place. You can not get much faster/less computational then that unless you have special domainknowledge about your lists that would make programming a specialized in-place-sorter as replacement for list.sort() viable.


On Python 3 (thanks @Matthias Profil) comparison between int ansd str give TypeError - you can "fix" that with some optional computation ( inspired by answers at: python-list-sort-query-when-list-contains-different-element-types ):

def IsString(item):    
    return isinstance(item,str)
def IsInt(item):
    return isinstance(item,int)

a= {'a':1, 'b': [2,8,4,3], 'c':['c',5,7,'a',6]} # changed c and a to be strings

for e in a:
    if isinstance(a[e],list):
        try:
            a[e].sort()         # inplace sort the lists
        except TypeError:
            str_list = sorted(filter(IsString,a[e]))
            int_list = sorted(filter(IsInt,a[e]))
            a[e] = int_list + str_list # default to numbers before strings

print(a)
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • 1
    With a mix of integers and strings you'll get the following error: `TypeError: '<' not supported between instances of 'int' and 'str'`. On Python 2 it might work. – Matthias Oct 18 '18 at 12:41
  • 1
    @Matthias you are right - seems I had pyfiddle.org set to 2.7 - my bad. I am unable to remove the answer unless the accept gets removed. I see If I find a workaround. – Patrick Artner Oct 18 '18 at 13:16
  • 1
    This Q [python-list-sort-query-when-list-contains-different-element-types](https://stackoverflow.com/questions/20872314/python-list-sort-query-when-list-contains-different-element-types) gives some hints on how to fix it - unfortunately either one creates new lists (sperate into datataypes, sort independently, join afterwards OR create strings from all and sort by that) or needs perdefeinerd __lt__ operators which one would have to monkey patch into int/string if possible :/ – Patrick Artner Oct 18 '18 at 13:20
0

In general (if your values are list of comparable items, eg numbers only), you could do something like this

sorted_dict = {key: sorted(value) for key, value in original_dict.items()}

If your values are single numbers/strings, you should change sorted(value) to sorted(value) if isinstance(value, list) else value. (thanks to user @DeepSpace for pointing out).

However, the example you give in not valid, unless a and c refer to integer values.

blue_note
  • 27,712
  • 9
  • 72
  • 90