Python 将namedtuple转换为字典

Python 将namedtuple转换为字典,python,dictionary,tuples,namedtuple,Python,Dictionary,Tuples,Namedtuple,我在python中有一个命名的元组类 class Town(collections.namedtuple('Town', [ 'name', 'population', 'coordinates', 'population', 'capital', 'state_bird'])): # ... 我想把城镇实例转换成字典。我不希望它被严格地束缚在一个城镇的土地名称或数量上 有没有一种方法可以编写它,这样我就可以添加更多的字段,或者传入

我在python中有一个命名的元组类

class Town(collections.namedtuple('Town', [
    'name', 
    'population',
    'coordinates',
    'population', 
    'capital', 
    'state_bird'])):
    # ...
我想把城镇实例转换成字典。我不希望它被严格地束缚在一个城镇的土地名称或数量上

有没有一种方法可以编写它,这样我就可以添加更多的字段,或者传入一个完全不同的命名元组并获得一个字典


我不能改变原来的类定义,因为它在其他人的代码中。因此,我需要以一个城镇为例,将其转换为字典。

TL;DR:有一种方法可以解决这个问题

以下是该用法的演示:

>>> fields = ['name', 'population', 'coordinates', 'capital', 'state_bird']
>>> Town = collections.namedtuple('Town', fields)
>>> funkytown = Town('funky', 300, 'somewhere', 'lipps', 'chicken')
>>> funkytown._asdict()
OrderedDict([('name', 'funky'),
             ('population', 300),
             ('coordinates', 'somewhere'),
             ('capital', 'lipps'),
             ('state_bird', 'chicken')])
这是一个命名的元组,也就是说,与python中通常的约定不同,方法名称上的前导下划线不用于阻止使用。除了添加到namedtuples的其他方法,
\u make
\u replace
\u source
\u fields
,它的下划线仅用于尝试和防止与可能的字段名发生冲突


注意:对于一些2.7.5
>>> vars(funkytown)
OrderedDict([('name', 'funky'),
             ('population', 300),
             ('coordinates', 'somewhere'),
             ('capital', 'lipps'),
             ('state_bird', 'chicken')])

有一段时间,文档提到asdict已过时(请参阅),并建议使用内置方法。这个建议现在已经过时了;为了修复与子类化相关的问题,namedtuples上存在的
\uuu dict\uuu
属性再次被删除

namedtuple
实例上有一个内置的方法


正如在评论中所讨论的,在某些版本上,
vars()
也会这样做,但它显然高度依赖于构建细节,而
\u asdict
应该是可靠的。在某些版本中,
\u asdict
被标记为已弃用,但注释表明,从3.4开始,情况就不再如此。

在Ubuntu 14.04 LTS版本的python2.7和python3.4上,
\u dict\uuu
属性按预期工作。asdict的
\u asdict
方法也起作用,但我倾向于使用标准定义的统一属性api,而不是本地化的非统一api

$python2.7

# Works on:
# Python 2.7.6 (default, Jun 22 2015, 17:58:13)  [GCC 4.8.2] on linux2
# Python 3.4.3 (default, Oct 14 2015, 20:28:29)  [GCC 4.8.4] on linux

import collections

Color = collections.namedtuple('Color', ['r', 'g', 'b'])
red = Color(r=256, g=0, b=0)

# Access the namedtuple as a dict
print(red.__dict__['r'])  # 256

# Drop the namedtuple only keeping the dict
red = red.__dict__
print(red['r'])  #256
认为dict是获取表示soemthing的词典的语义方法(至少据我所知)


如果能积累一个主要python版本和平台及其对
\uuuu dict\uuuu
的支持的表格就好了,目前我只有一个平台版本和两个python版本,如上所述

| Platform                      | PyVer     | __dict__ | _asdict |
| --------------------------    | --------- | -------- | ------- |
| Ubuntu 14.04 LTS              | Python2.7 | yes      | yes     |
| Ubuntu 14.04 LTS              | Python3.4 | yes      | yes     |
| CentOS Linux release 7.4.1708 | Python2.7 | no       | yes     |
| CentOS Linux release 7.4.1708 | Python3.4 | no       | yes     |
| CentOS Linux release 7.4.1708 | Python3.6 | no       | yes     |

Python 3。将任何字段分配给字典作为字典所需的索引,我使用了“name”

import collections

Town = collections.namedtuple("Town", "name population coordinates capital state_bird")

town_list = []

town_list.append(Town('Town 1', '10', '10.10', 'Capital 1', 'Turkey'))
town_list.append(Town('Town 2', '11', '11.11', 'Capital 2', 'Duck'))

town_dictionary = {t.name: t for t in town_list}
案例1:一维元组

TUPLE_ROLES = (
    (912,"Role 21"),
    (913,"Role 22"),
    (925,"Role 23"),
    (918,"Role 24"),
)


TUPLE_ROLES[912]  #==> Error because it is out of bounce. 
TUPLE_ROLES[  2]  #==> will show Role 23.
DICT1_ROLE = {k:v for k, v in TUPLE_ROLES }
DICT1_ROLE[925] # will display "Role 23" 
案例2:二维元组
示例:DICT_角色[961]#将显示“后端程序员”

NAMEDTUPLE_ROLES = (
    ('Company', ( 
            ( 111, 'Owner/CEO/President'), 
            ( 113, 'Manager'),
            ( 115, 'Receptionist'),
            ( 117, 'Marketer'),
            ( 119, 'Sales Person'),
            ( 121, 'Accountant'),
            ( 123, 'Director'),
            ( 125, 'Vice President'),
            ( 127, 'HR Specialist'),
            ( 141, 'System Operator'),
    )),
    ('Restaurant', ( 
            ( 211, 'Chef'), 
            ( 212, 'Waiter/Waitress'), 
    )),
    ('Oil Collector', ( 
            ( 211, 'Truck Driver'), 
            ( 213, 'Tank Installer'), 
            ( 217, 'Welder'),
            ( 218, 'In-house Handler'),
            ( 219, 'Dispatcher'),
    )),
    ('Information Technology', ( 
            ( 912, 'Server Administrator'),
            ( 914, 'Graphic Designer'),
            ( 916, 'Project Manager'),
            ( 918, 'Consultant'),
            ( 921, 'Business Logic Analyzer'),
            ( 923, 'Data Model Designer'),
            ( 951, 'Programmer'),
            ( 953, 'WEB Front-End Programmer'),
            ( 955, 'Android Programmer'),
            ( 957, 'iOS Programmer'),
            ( 961, 'Back-End Programmer'),
            ( 962, 'Fullstack Programmer'),
            ( 971, 'System Architect'),
    )),
)

#Thus, we need dictionary/set

T4 = {}
def main():
    for k, v in NAMEDTUPLE_ROLES:
        for k1, v1 in v:
            T4.update ( {k1:v1}  )
    print (T4[961]) # will display 'Back-End Programmer'
    # print (T4) # will display all list of dictionary

main()
如果没有_asdict(),则可以使用以下方法:

def to_dict(model):
    new_dict = {}
    keys = model._fields
    index = 0
    for key in keys:
        new_dict[key] = model[index]
        index += 1

    return new_dict
通常
\u asdict()
返回一个
OrderedDict
。这是如何从
OrderedDict
转换为常规
dict


town=town('funky',300,'somewhere','lipps','chicken')
dict(town.\u asdict())
输出将是

{'capital': 'lipps',
 'coordinates': 'somewhere',
 'name': 'funky',
 'population': 300,
 'state_bird': 'chicken'}

顺便提一下查看制表符完成或
dir
命令,它将显示任何对象的字段。。。这将直接显示
\u asdict
函数。看起来您真正想要做的是从
dict
中创建子类,而不是“namedtuple”,并将namedtuple传递给初始值设定项。请记住,如果您习惯于Cxx,
class Town(x)
不是构造函数,
def\uuu init\uuuuuuuuuself,*args,**kwargs)
在它里面。我不能更改原始类,因为它在其他人的代码中。所以我必须从namedtouble@CorleyBrigman你能再解释一下吗?我试图在命名的touple上找到文档,或者找到我可以调用的内容,但我不知道如何找到。(同样,python不是我最强的语言)哪一部分
dir
只是一个python内置的。。。您可以在任何python对象、控制台或脚本中运行它(它返回一个可以打印或执行任何操作的列表),并且它将返回对象(几乎)所有属性的列表。如果你想弄清楚未知对象是如何工作的,这很有帮助。我不是下选者,但这可能是因为
\u asdict
方法相反,看起来
vars
在一些旧版本上不起作用-在2.7上,它会引发
类型错误,由于该版本的
namedtuple
类没有
\uuu dict\uuuu
属性。是的,Martijn和我已经讨论过这个问题。它将在更新版本的2.7 btw上工作(我在2.7.6上,它可以工作)超过我上面评论的编辑窗口-它在2.7.5上失败,因此它必须是从2.7.6开始的新版本。除非我的2.7.5版本被关闭,就像Martijn在链接答案上那样?无论如何,它是否能在2.7.5上工作似乎取决于构建细节。请注意:_asdict不再是obseleted(现在返回OrderedDict),vars在Python 3.4中产生错误(从namedtuples的dict属性中删除).有谁知道是否有一个既定的先例表明标准库中不应将
\u asdict
别名为
asdict
?@KobeJohn那么你就不能让
“asdict”
成为元组名称之一。这对你来说毫无帮助,因为你知道名称就在那里。它应该是一种盲法Linux-3.10.0-693.el7.x86-64-x86-64-with-centos-7.4.1708-Core,Python 2.7--
\u dict\u
不起作用。