Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unpack dictionary in order that it was passed?

This is the following problem:

main_module.py

from collections import OrderedDict
from my_other_module import foo

a = OrderedDict([
    ('a', 1),
    ('b', 2),
    ('c', 3),
    ('d', 4),
    ])

foo(**a)

my_other_module.py

def foo(**kwargs):
    for k, v in kwargs.items():
        print k, v

When i run main_module.py I'm expecting to get printout with the order I specified:

a 1
b 2
c 3
d 4

But instead I'm getting:

a 1
c 3
b 2
d 4

I do understand that this has something to do with the way ** operator is implemented and somehow it looses order how dictionary pairs are passed in. Also I do understand that dictionaries in python are not ordered as lists are, because they're implemented as hash tables. Is there any kind of 'hack' that I could apply so I get the behaviour that is needed in this context?

P.S. - In my situation I can't sort the dictionary inside foo function since there are no rules which could be followed except strict order that values are passed in.

like image 789
Sir DrinksCoffeeALot Avatar asked Dec 13 '22 16:12

Sir DrinksCoffeeALot


1 Answers

By using **a you're unpacking the ordered dictionary into an argument dictionary.

So when you enter in foo, kwargs is just a plain dictionary, with order not guaranteed (unless you're using Python 3.6+, but that's still an implementation detail in 3.6 - the ordering becomes official in 3.7: Are dictionaries ordered in Python 3.6+?)

You could just lose the packing/unpacking in that case so it's portable for older versions of python.

from collections import OrderedDict

def foo(kwargs):
    for k, v in kwargs.items():
        print(k, v)

a = OrderedDict([
    ('a', 1),
    ('b', 2),
    ('c', 3),
    ('d', 4),
    ])

foo(a)
 
like image 131
Jean-François Fabre Avatar answered Dec 29 '22 12:12

Jean-François Fabre