Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort dictionary into list

There are already a lot of questions about sorting dictionaries but I can't find the right answer to my question.

I have the dictionary v:

v = {3:4.0, 1:-2.0, 10:3.5, 0:1.0}

We have to turn the dictionary v into a sorted list.

lijst(v) = [1.0, -2.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.5]

I have tried working with this code:

def lijst(x):
    return sorted(x.items(), key=lambda x: x[1])

This is the list I receive:

lijst(v) = [(1, -2.0), (0, 1.0), (10, 3.5), (3, 4.0)]

Does anyone know how to convert this into a list of values sorted in order of their key, with the missing values padded with zero?

like image 542
itseva Avatar asked Aug 02 '17 18:08

itseva


2 Answers

Just use itertools.chain.from_iterable to flatten your result (the list of tuples):

>>> import itertools

>>> list(itertools.chain.from_iterable([(1, -2.0), (0, 1.0), (10, 3.5), (3, 4.0)]))
[1, -2.0, 0, 1.0, 10, 3.5, 3, 4.0]

In case I misunderstood your original request and the dictionary represents a "sparse vector" (where the keys are the indices) you could simply populate a list containing only zeros:

>>> res = [0.0]*(max(v)+1)       # create a dummy list containing only zeros
>>> for idx, val in v.items():   # populate the requested indices
...     res[idx] = val 
>>> res
[1.0, -2.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.5]

Or if you have NumPy you could also avoid the for-loop:

>>> import numpy as np

>>> arr = np.zeros(max(v)+1)
>>> arr[list(v.keys())] = list(v.values())
>>> arr
array([ 1. , -2. ,  0. ,  4. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  3.5])

The last approach relies on the fact that even though the order of keys and values is arbitrary they nevertheless directly correspond as long as there is no modification of the dictionary:

Keys and values are iterated over in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary’s history of insertions and deletions. If keys, values and items views are iterated over with no intervening modifications to the dictionary, the order of items will directly correspond.

Source 4.10.1. Dictionary view objects

like image 80
MSeifert Avatar answered Sep 21 '22 15:09

MSeifert


You can try this using chain from itertools:

from itertools import chain

v = {3:4.0, 1:-2.0, 10:3.5, 0:1.0}

final_output = list(chain(*sorted(v.items(), key=lambda x: x[1])))

Output:

[1, -2.0, 0, 1.0, 10, 3.5, 3, 4.0]
like image 29
Ajax1234 Avatar answered Sep 19 '22 15:09

Ajax1234