What is the most pythonic way to sort a dict with list values?

Viewed 128

I am creating a dictionary with values as a list of integers. What is the pythonic way to sort the values for each key? In my approach I am overwriting each key value after sorting.

Is there a way to maintain the sorting on insertion into the dictionary or is it better to store first and then sort the values efficiency wise?

my_dict = {
'first': [3,6,99],
'second': [1,-10,100],
'third': [5,0,23,67,29]
}

# my approach
for key, values in my_dict.items():
    my_dict[key] = sorted(values)

Ouput:

my_dict = {
'first': [3,6,99],
'second': [-10,1,100],
'third': [0,5,23,29,67]
}

3 Answers

You were almost there, you want to sort the lists in place, so use list.sort:

my_dict = {
    'first': [3,6,99],
    'second': [1,-10,100],
    'third': [5,0,23,67,29]
}

for val in my_dict.values():
    val.sort()

Live demo

Check this sorting how to guide

Solution:

pythonic code makes use of programming patterns such as list comprehensions or generator expressions, attempt to crowbar in patterns more commonly used in C or java. Loops are particularly common examples of this.Pythonic code also makes use of inline sintaxes as mentioned by PEP20(Beautiful is better than ugly., Flat is better than nested.)

Firstly, your code is good but to be more pythonic you should make use of sytaxes such as list comprehnsions/dict comprehensions. I will cover the most efficient way that has the least lines of code using a dict comprehension instaed of a for loop to be more pythonic even hough for loops are considered to be pyhonic list & dict comprehensions are more pythonic(they are flat syntaxes).

Here is the code:

my_dict = {
'first': [3,6,99],
'second': [1,-10,100],
'third': [5,0,23,67,29]
}

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

Output:

{'first': [3, 6, 99], 'second': [-10, 1, 100], 'third': [0, 5, 23, 29, 67]}

Local sorting does not need to assign a value to the key again.

import random
import time
from copy import deepcopy


def time_it(func):
    def inner():
        start = time.time()
        func()
        end = time.time()
        print('time used:{} second'.format(end - start))

    return inner


def random_l(n):
    return [random.randint(0, 100) for _ in range(n)]


my_dict = {
    'first': random_l(5),
    'second': random_l(5),
    'third': random_l(5)
}
my_dict1 = deepcopy(my_dict)
my_dict2 = deepcopy(my_dict)


@time_it
def foo():
    print(my_dict1)
    for key, values in my_dict1.items():
        my_dict1[key] = sorted(values)
    print(my_dict1)


@time_it
def bar():
    print(my_dict2)
    for key, values in my_dict2.items():
        sorted(my_dict2[key])
    print(my_dict2)


if __name__ == '__main__':
    foo()
    bar()

{'first': [28, 96, 52, 57, 93], 'second': [17, 89, 76, 30, 36], 'third': [73, 32, 9, 90, 81]}
{'first': [28, 52, 57, 93, 96], 'second': [17, 30, 36, 76, 89], 'third': [9, 32, 73, 81, 90]}
time used:5.3882598876953125e-05 second
{'first': [28, 96, 52, 57, 93], 'second': [17, 89, 76, 30, 36], 'third': [73, 32, 9, 90, 81]}
{'first': [28, 96, 52, 57, 93], 'second': [17, 89, 76, 30, 36], 'third': [73, 32, 9, 90, 81]}
time used:1.621246337890625e-05 second

If you want a feature like sortedList sortedcontainers is convenient, or you can use the insort function of the bitsect module

Related