Skip to content

Instantly share code, notes, and snippets.

@href
Created October 27, 2011 12:00
Show Gist options
  • Star 62 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save href/1319371 to your computer and use it in GitHub Desktop.
Save href/1319371 to your computer and use it in GitHub Desktop.
Convert any dictionary to a named tuple
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
"""
@malcolmgreaves
Copy link

malcolmgreaves commented Dec 11, 2018

I wrote up this [1] implementation a little while ago. Stumbled upon this thread. From the namedtuple_fmt module, the serialize function accepts a dictionary (e.g. from a json.load call) and will convert to an instance of the given namedtuple-deriving type. Likewise, deserialize will convert any namedtuple-deriving type into a dictionary-l object. These functions also work on any list-like type: List and Tuple are process-able.

E.g.

import json
from typing import Sequence

from namedtuple_fmt import serialize, deserialize

X = NamedTuple('X', [('msg',str)])

json_str="""{"msg": "This is the first message"}"""
first_msg = deserialize(json.loads(json_str), X) 
print(first_msg.msg)
print(deserialize(serialize(first_msg)) == X("This is the first message"))
print(deserialize(json.loads(json.dumps(serialize(first_msg)))) == X("This is the first message"))

json_str="""[{"msg": "This is the first message"},{"msg": "This is the 2nd message"}]"""
messages = deserialize(json.loads(json_str), Sequence[X])
print(f"{len(messages)} messages")
print('\n'.join(map(lambda x: x.msg, messages))

Implementation note: There are explicit type checks for the Sequence types. It's important to not mess-up when it comes to handling str and tuple. A first draft of this idea incorrectly did for _ in X when trying to "test" if something was list-like. This idea, unfortunately, will iterate over characters in a str or elements in a tuple. We want the tuple-iterating part, but not when it comes to a NamedTuple (or namedtuple)!

[1] https://gist.github.com/malcolmgreaves/d71ae1f09075812e54d8ec54a5613616

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment