from collections import namedtuple | |
def convert(dictionary): | |
return namedtuple('GenericDict', dictionary.keys())(**dictionary) | |
""" | |
>>> d = dictionary(a=1, b='b', c=[3]) | |
>>> named = convert(d) | |
>>> named.a == d.a | |
True | |
>>> named.b == d.b | |
True | |
>>> named.c == d.c | |
True | |
""" |
This comment has been minimized.
This comment has been minimized.
This is nice, I have to convert a JSON object to a |
This comment has been minimized.
This comment has been minimized.
I can. The function def func(kwarg=None):
return kwarg
derp = { 'kwarg': 39 } ...then I can call If you look at def convert(dictionary):
NT = namedtuple('GenericDict', dictionary.keys())
gen_dict = NT(**dictionary)
return gen_dict ...the same thing would happen. But this way, it might be a little clearer. |
This comment has been minimized.
This comment has been minimized.
A neat idea!
|
This comment has been minimized.
This comment has been minimized.
Thanks. Added code to convert it recursively. from collections import namedtuple
def convert(dictionary):
for key, value in dictionary.iteritems():
if isinstance(value, dict):
dictionary[key] = convert(value)
return namedtuple('GenericDict', dictionary.keys())(**dictionary) |
This comment has been minimized.
This comment has been minimized.
I have a variation to propose, in which you're 100% sure it will continue to work if new members are added to the dict (json API evolving):
Blah(a1=1, a2=2, a3=3) |
This comment has been minimized.
This comment has been minimized.
I'd like to point out the performance of this. For a dictionary of 20 keys the conversion takes 500 us on my machine. Member access is about 3 times slower than of original dict. That's on cpython. On pypy surprisingly conversion takes a about 1 ms (2 times slower than cpython) and access is a little bit faster in nametuple. The process of creating a namedtuple is taking most of the time of convertion. |
This comment has been minimized.
This comment has been minimized.
For a quick and dirty dict keys to object attrs conversion, I use import mock
d = dict(a=1, b='b')
o = mock.Mock(**d)
assert d['a'] == o.a
assert d['b'] == o.b |
This comment has been minimized.
This comment has been minimized.
This approach is likely to be error prone because python dictionaries aren't ordered but namedtuple is ordered. You could get different positions in the tuple for different fields from run to run. For example, this program (when using Python 3.4.X) occasionally throws an error. Run it a few times to reproduce it.
The error looks like this:
|
This comment has been minimized.
This comment has been minimized.
I added support for list values to suganthsundar's solution:
|
This comment has been minimized.
This comment has been minimized.
Above code breaks if the item of the list is not a dictionary. Modifying the code as following, which should work for most of the cases:
|
This comment has been minimized.
This comment has been minimized.
Thanks for this! |
This comment has been minimized.
This comment has been minimized.
@JinghongHuang The snippet you posted above has bad performance because it creates many |
This comment has been minimized.
This comment has been minimized.
Anyone interested in this should also check out the |
This comment has been minimized.
This comment has been minimized.
I wrote up this [1] implementation a little while ago. Stumbled upon this thread. From the E.g.
Implementation note: There are explicit type checks for the [1] https://gist.github.com/malcolmgreaves/d71ae1f09075812e54d8ec54a5613616 |
This comment has been minimized.
GenericDict will have different fields: