Pythonic way to convert a dictionary into namedtuple or another hashable dict-like? Pythonic way to convert a dictionary into namedtuple or another hashable dict-like? python python

Pythonic way to convert a dictionary into namedtuple or another hashable dict-like?


To create the subclass, you may just pass the keys of a dict directly:

MyTuple = namedtuple('MyTuple', d)

Now to create tuple instances from this dict, or any other dict with matching keys:

my_tuple = MyTuple(**d)

Beware: namedtuples compare on values only (ordered). They are designed to be a drop-in replacement for regular tuples, with named attribute access as an added feature. The field names will not be considered when making equality comparisons. It may not be what you wanted nor expected from the namedtuple type! This differs from dict equality comparisons, which do take into account the keys and also compare order agnostic.

For readers who don't really need a type which is a subclass of tuple, there probably isn't much point to use a namedtuple in the first place. If you just want to use attribute access syntax on fields, it would be simpler and easier to create namespace objects instead:

>>> from types import SimpleNamespace>>> SimpleNamespace(**d)namespace(a=1, b=2, c=3, d=4)

my reason for wanting to convert my dictionary to a namedtuple is so that it becomes hashable, but still generally useable like a dict

For a hashable "attrdict" like recipe, check out a frozen box:

>>> from box import Box>>> b = Box(d, frozen_box=True)>>> hash(b)7686694140185755210>>> b.a1>>> b["a"]1>>> b["a"] = 2BoxError: Box is frozen

There may also be a frozen mapping type coming in a later version of Python, watch this draft PEP for acceptance or rejection:

PEP 603 -- Adding a frozenmap type to collections


from collections import namedtuplent = namedtuple('x', d.keys())(*d.values())


I'd like to recommend the dataclass for this type of situation. Similar to a namedtuple, but with more flexibility.

https://docs.python.org/3/library/dataclasses.html

from dataclasses import dataclass@dataclassclass InventoryItem:    """Class for keeping track of an item in inventory."""    name: str    unit_price: float    quantity_on_hand: int = 0    def total_cost(self) -> float:        return self.unit_price * self.quantity_on_hand