Pythonic将字典转换为namedtuple的方法,还是另一个Hashable dict-like?

Max*_*wer 39 python dictionary namedtuple

我有一个字典,如:

d = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
Run Code Online (Sandbox Code Playgroud)

我想将其转换为namedtuple.我目前的方法是使用以下代码

namedTupleConstructor = namedtuple('myNamedTuple', ' '.join(sorted(d.keys())))
nt= namedTupleConstructor(**d)
Run Code Online (Sandbox Code Playgroud)

哪个产生

myNamedTuple(a = 1,b = 2,c = 3,d = 4)

这对我来说很好(我认为),但我错过了内置如...

nt = namedtuple.from_dict() ?
Run Code Online (Sandbox Code Playgroud)

更新:正如评论中所讨论的那样,我想将我的字典转换为一个命名元组的原因是它变得可以清洗,但仍然像dict一样可用.

wim*_*wim 61

要创建子类,您可以直接传递dict的键:

MyTuple = namedtuple('MyTuple', sorted(d))
Run Code Online (Sandbox Code Playgroud)

现在从这个dict或其他具有匹配键的dicts创建实例:

my_tuple = MyTuple(**d)
Run Code Online (Sandbox Code Playgroud)

注意: namedtuples 仅对值进行比较(有序).它们被设计为常规元组的替代品,命名属性访问作为附加功能. 进行相等比较时,不会考虑字段名称.这与dict等式比较不同,后者考虑了键,它可能不是您想要的namedtuple类型!

如果你只有一个字典,而不是一堆字母共享同一组密钥,那么首先创建这个名字元组是没有意义的.您应该只使用命名空间对象:

>>> from types import SimpleNamespace
>>> SimpleNamespace(**d)
namespace(a=1, b=2, c=3, d=4)
Run Code Online (Sandbox Code Playgroud)

对于像食谱一样的可清洗"attrdict",请查看一个冷冻盒子:

>>> from box import Box
>>> b = Box(d, frozen_box=True)
>>> hash(b)
7686694140185755210
>>> b.a
1
>>> b['a']
1
Run Code Online (Sandbox Code Playgroud)

  • 对于单行代码,您需要:MyNamedTuple = namedtuple('MyNamedTuple',d.keys())(** d) (2认同)
  • @MaxPower:您是否知道从{{a':1}`和`{'b':1}`构造的namedtuple将相等,并且具有相等的哈希码?诸如“ tuple(sorted(d.items()))”或“ frozenset(d.items())”之类的东西可能更合适。他们还将处理不是有效的Python标识符的键,例如“'for'`或'3'。 (2认同)

Mit*_*dra 13

from collections import namedtuple
nt = namedtuple('x', d.keys())(*d.values())
Run Code Online (Sandbox Code Playgroud)


TLK*_*LK3 9

我想推荐针对这种情况的数据类。与命名元组类似,但具有更大的灵活性。

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

from dataclasses import dataclass

@dataclass
class 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
Run Code Online (Sandbox Code Playgroud)


toi*_*ing 8

如果您想要一种更简单的方法,并且您可以灵活地使用除namedtuple我建议使用SimpleNamespace文档)之外的另一种方法。

from types import SimpleNamespace as sn

d = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
dd= sn(**d)
# dd.a>>1

# add new property
dd.s = 5
#dd.s>>5
Run Code Online (Sandbox Code Playgroud)

PS:SimpleNamespace是一种类型,而不是一个类