명명 된 튜플을 사전으로 변환


148

파이썬에 명명 된 튜플 클래스가 있습니다.

class Town(collections.namedtuple('Town', [
    'name', 
    'population',
    'coordinates',
    'population', 
    'capital', 
    'state_bird'])):
    # ...

Town 인스턴스를 사전으로 변환하고 싶습니다. 나는 그것이 도시의 이름이나 필드의 수에 단단히 묶여 있기를 원하지 않습니다.

더 많은 필드를 추가하거나 완전히 다른 이름의 튜플을 전달하고 사전을 얻을 수 있도록 작성하는 방법이 있습니까?

다른 사람의 코드에서와 같이 원래 클래스 정의를 변경할 수 없습니다. 따라서 Town의 인스턴스를 가져 와서 사전으로 변환해야합니다.


2
btw ... 탭 완성 또는 dir명령을 보면, _asdict기능을 직접 보여줄 개체의 필드가 표시 됩니다.
Corley Brigman

당신이 것 같습니다 정말 하고 싶은 것은에서 하위 클래스입니다 dict대신 'namedtuple', 그리고 이니셜로 namedtuple를 전달합니다. Cxx에 익숙하다면 class Town(x)생성자가 아니며 def __init__(self, *args, **kwargs)내부에 있습니다.
Corley Brigman

다른 사람의 코드에서와 같이 원래 클래스를 변경할 수 없습니다. 나는 namedtouble에서 서브 클래스에 그래서
나 그것은 그냥 Aweso없이

@CorleyBrigman 이것에 대해 더 자세히 설명해 주시겠습니까? 이름이 지정된 touple에서 문서를 찾거나 호출 할 수있는 것을 찾으려고 시도했지만 방법을 알 수 없었습니다. (다시 파이썬은 나의 가장 강한 언어가 아니다)
나없이 그냥 Aweso

2
어느 부분? dir단지 파이썬 내장되어 ... 당신은 그것을 실행할 수 있는 거의 (콘솔이나 스크립트 (이 목록을 반환 위치를 인쇄하거나 함께 무엇을 할 수있는)에서, 파이썬 객체, 그리고 그것을 목록을 반환합니다 ) 객체의 모든 속성 알 수없는 객체의 작동 방식을 파악하려고 할 때 유용합니다.
Corley Brigman

답변:


268

TL; DR : _asdict이를 위해 제공 되는 방법 이 있습니다.

사용법에 대한 데모는 다음과 같습니다.

>>> 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')])

이것은 문서화 된 명명 된 튜플 방법 입니다. 즉, 파이썬 일반적인 규칙과 달리 메소드 이름의 밑줄은 사용을 방해하지 않습니다 . namedtuples에 추가 된 다른 방법과 함께, _make, _replace, _source, _fields, 그것은 단지 시도하고 가능한 필드 이름과의 충돌을 방지하기 위해 밑줄이 있습니다.


참고 : 일부 2.7.5 <python version <3.5.0 코드가 다음과 같이 표시되면이 버전이 표시 될 수 있습니다.

>>> vars(funkytown)
OrderedDict([('name', 'funky'),
             ('population', 300),
             ('coordinates', 'somewhere'),
             ('capital', 'lipps'),
             ('state_bird', 'chicken')])

잠시 동안 문서에서 언급 _asdict되지 않았으며 ( 여기 참조 ) 내장 메소드 vars 사용을 제안했습니다 . 그 조언은 이제 구식입니다. 서브 클래 싱과 관련된 버그 를 수정하기 위해 __dict__named_tuples에 있던 속성 이이 commit에 의해 다시 제거되었습니다 .


1
_asdict표준 라이브러리에서 별칭을 지정해서는 안되는 기존의 선례가 있는지 아는 사람이 asdict있습니까?
KobeJohn

1
@ KobeJohn 그러면 "asdict"튜플 이름 중 하나 가 될 수 없었습니다 .
shadowtalker

28

namedtuple이를 위해 인스턴스에 내장 메소드가 _asdict있습니다.

의견에서 논의했듯이 일부 버전에서는 vars()그렇게 할 것이지만 빌드 세부 사항에 크게 의존하는 반면 _asdict신뢰할 수 있어야합니다. 일부 버전에서는 _asdict더 이상 사용되지 않는 것으로 표시되었지만 의견에 따르면 더 이상 3.4에서 그렇지 않습니다.


1
나는 downvoter가 아니었지만, 그 _asdict방법은 python3
wim

반대로, vars일부 이전 버전에서는 작동 하지 않는 것 같습니다 . 2.7에서는 TypeError버전의 namedtuple클래스에 __dict__속성이 없으므로을 발생시킵니다.
Peter DeGlopper

그렇습니다. Martijn과 저는 여기서 논의했습니다 . 그것은 2.7 btw의 새로운 버전에서 작동합니다 (2.7.6에 있고 작동합니다)
wim

위의 주석에 편집 창을 붙여 넣으면 2.7.5에서 실패하므로 2.7.6부터 새로 워야합니다. Martijn이 링크 된 답변에 따라 2.7.5 빌드가 꺼져 있지 않으면? 어쨌든 2.7.5에서 작동하는지 여부는 빌드 사양에 따라 다릅니다.
Peter DeGlopper

8
_asdict는 더 이상 지원되지 않으며 (지금 OrderedDict를 반환) vars는 Python 3.4에서 오류를 생성합니다 ( namedtuples 의 dict 속성 제거에서 ).
Alexander Huszagh

2

Ubuntu 14.04 LTS 버전의 python2.7 및 python3.4에서 __dict__속성이 예상대로 작동했습니다. 이 _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을 나타내는 사전을 얻는 의미 론적 방법입니다 (적어도 내 지식으로는 최선입니다).


주요 파이썬 버전 및 플랫폼 테이블과에 대한 지원을 축적하는 것이 좋을 것입니다 __dict__. 현재 위에 게시 된대로 하나의 플랫폼 버전과 두 개의 파이썬 버전 만 있습니다.

| 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     |

1
Linux-3.10.0-693.el7.x86_64-x86_64-with-centos-7.4.1708-Core, Python 2.7- __dict__작동하지 않습니다.
gbtimmon

-1

사례 # 1 : 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 : 2 차원 튜플
예 : DICT_ROLES [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()

-1

_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

-5

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}

이름이 있다는 것을 알고 도움이되지 않습니다. 그것은 맹인 방법이어야합니다
Mitchell Currie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.