Sort dictionary by increasing length of its values Given a dictionary where the values are iterables, print the dictionary sorted by the length of its values.

def sort_dict_by_value_len(lst):
    while lst:
        min_key = min([(len(v), k) for (k, v) in lst.items()])
        print(min_key[1], lst.pop(min_key[1]))

sort_dict_by_value_len({1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten'})


1 one
2 two
6 six
10 ten
4 four
5 five
9 nine
3 three
7 seven
8 eight


I feel like I'm doing too much computations, and worst of all, I'm emptying the input list. Is there any better way to achieve this, with or without using sort or sorted, and optionally keeping the dictionary intact?
Calling a dictionary a list is very confusing
Rather than using min, you could use sorted.

This'll change the time complexity of your code from \$O(n^2)\$ to \$O(n \log n)\$, as Python uses the Timsort. And since sorted is written in C, it'll be super fast too.

Sorted also has the keyword argument key, which lets you sort by another value, rather than the value you get.

This also keeps the original dictionary intact.
You can use dict and enumerate to build your input list. And to build a list to pass to enumerate you could use str.split.


And so I'd change your code to:

def sort_dict_by_value_len(dict_):
    return sorted(dict_.items(), key=lambda kv: (len(kv[1]), kv[0]))

def sort_dict_by_value_len_without_key(dict_):
    return [(k, dict_[k]) for _, k in sorted((len(v), k) for (k, v) in dict_.items())]

dict_ = dict(enumerate('one two three four five six seven eight nine ten'.split(), start=1))
for key, value in sort_dict_by_value_len(dict_):
    print(key, value)




If you only want \$O(1)\$ memory usage, then you could use an insertion sort. But keeps the \$O(n^2)\$ time complexity. I also cheated a bit.


I used a generator comprehension, rather than a list comprehension to ensure \$O(1)\$ space. Alternately, you could invert the algorithm, and pop from one array to another.
I used bisect.insort to remove most of the logic.




def sort_dict_by_value_len(dict_):
    output = []
    while dict_:
        key, value = dict_.popitem()
        bisect.insort(output, ((len(value), key), (key, value)))
    return (i[1] for i in output)