แปลง tuple ที่มีชื่อเป็นพจนานุกรม


148

ฉันมีคลาส tuple ชื่อในหลาม

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

ฉันต้องการแปลงอินสแตนซ์ทาวน์เป็นพจนานุกรม ฉันไม่ต้องการให้มันผูกติดอยู่กับชื่อหรือจำนวนของฟิลด์ในเมือง

มีวิธีเขียนเช่นนี้หรือไม่ที่ฉันสามารถเพิ่มเขตข้อมูลเพิ่มเติมหรือส่งชื่อ tuple ที่แตกต่างไปจากเดิมอย่างสิ้นเชิงและรับพจนานุกรม

ฉันไม่สามารถแก้ไขคำจำกัดความของคลาสเดิมได้ในรหัสของผู้อื่น ดังนั้นฉันต้องใช้อินสแตนซ์ของเมืองและแปลงเป็นพจนานุกรม


2
btw ... ดูความสมบูรณ์ของแท็บหรือdirคำสั่งซึ่งจะแสดงฟิลด์สำหรับวัตถุใด ๆ ... ที่จะแสดง_asdictฟังก์ชั่นโดยตรง
Corley Brigman

ดูเหมือนว่าสิ่งที่คุณจริงๆต้องการจะทำคือประเภทรองจากdictแทน 'namedtuple' และผ่าน namedtuple ลง initializer โปรดจำไว้ว่าหากคุณคุ้นเคยกับ Cxx class Town(x)ไม่ใช่ผู้สร้างซึ่งdef __init__(self, *args, **kwargs)อยู่ภายใน
Corley Brigman

ฉันไม่สามารถเปลี่ยนคลาสเดิมได้ในรหัสของคนอื่น ดังนั้นฉันต้อง subclass จาก 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 คือแตกต่างจากการประชุมตามปกติในหลามขีดชั้นนำในชื่อวิธีการที่ไม่ได้มีการกีดกันการใช้ พร้อมกับวิธีการอื่น ๆ ที่เพิ่มให้กับ namedtuples, _make, _replace, _source, _fieldsแต่ก็มีขีดเดียวที่จะลองและป้องกันไม่ให้เกิดความขัดแย้งกับชื่อเขตที่เป็นไปได้


หมายเหตุ: สำหรับ 2.7.5 <python version <3.5.0 code out บางตัวคุณอาจเห็นเวอร์ชั่นนี้:

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

ในขณะที่เอกสารได้กล่าวถึงที่_asdictล้าสมัย (ดูที่นี่ ) และแนะนำให้ใช้ในตัววิธีvars คำแนะนำนั้นล้าสมัยแล้ว เพื่อแก้ไขข้อผิดพลาดที่เกี่ยวข้องกับ subclassing ที่__dict__สถานที่ให้บริการซึ่งเป็นปัจจุบันเกี่ยวกับ namedtuples ได้รับอีกครั้งถอดออกโดยการนี้กระทำการ


1
ไม่มีใครรู้ว่ามีแบบอย่างที่จัดตั้งขึ้นที่แนะนำ_asdictไม่ควรเป็นนามแฝงในห้องสมุดมาตรฐานเพื่อasdict?
KobeJohn

1
@KobeJohn แล้วคุณไม่"asdict"สามารถเป็นหนึ่งในชื่ออันดับ
shadowtalker

28

มีการสร้างขึ้นในวิธีการในกรณีนี้namedtuple_asdict

ตามที่กล่าวไว้ในความคิดเห็นในบางรุ่นvars()จะทำเช่นนั้น แต่ก็เห็นได้ชัดว่าขึ้นอยู่กับรายละเอียดการสร้างในขณะที่_asdictควรมีความน่าเชื่อถือ ในบางรุ่น_asdictถูกทำเครื่องหมายว่าเลิกใช้แล้ว แต่ความคิดเห็นระบุว่ากรณีนี้ไม่ได้เป็น 3.4


1
ฉันไม่ได้ downvoter แต่มันอาจจะเป็นเพราะ_asdictวิธีการที่ได้รับการจำหน่ายแล้วใน python3 (ในความโปรดปรานของ vars)
Wim

ในทางกลับกันดูเหมือนว่าจะvarsไม่ทำงานในเวอร์ชันเก่าบางรุ่น - ใน 2.7 จะเพิ่มขึ้นTypeErrorเนื่องจากnamedtupleคลาสของเวอร์ชันนั้นไม่มี__dict__แอตทริบิวต์
Peter DeGlopper

ใช่ Martijn และผมได้กล่าวถึงที่นี่ มันจะทำงานในรุ่นใหม่ของ 2.7 ครับ (ผมอยู่บน 2.7.6 และการทำงาน)
Wim

ผ่านหน้าต่างแก้ไขในความคิดเห็นด้านบนของฉัน - มันล้มเหลวใน 2.7.5 ดังนั้นจึงต้องใหม่เป็น 2.7.6 เว้นแต่ว่า 2.7.5 build ของฉันปิดอยู่ Martijn ก็อยู่ที่คำตอบที่เชื่อมโยงอยู่หรือไม่ อย่างไรก็ตามดูเหมือนว่าการทำงานกับ 2.7.5 ขึ้นอยู่กับรุ่นเฉพาะ
Peter DeGlopper

8
แค่หัวขึ้น: _asdict จะไม่ถูก obseleted อีกต่อไป (และส่งคืน OrderedDict ทันที) และ vars สร้างข้อผิดพลาดด้วย Python 3.4 (จากการลบแอ็ตทริบิวต์dictของ namedtuples)
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__ตอนนี้ฉันมีเพียงหนึ่งเวอร์ชันแพลทฟอร์มและเวอร์ชันหลามสองตัวที่โพสต์ไว้ด้านบน

| 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: tuple หนึ่งมิติ

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_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 จัดสรรฟิลด์ใด ๆ ให้กับพจนานุกรมเป็นดัชนีที่จำเป็นสำหรับพจนานุกรมฉันใช้ 'ชื่อ'

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.