Convert a namedtuple into a dictionary

后端 未结 6 1930
醉酒成梦
醉酒成梦 2020-12-04 18:36

I have a named tuple class in python

class Town(collections.namedtuple(\'Town\', [
    \'name\', 
    \'population\',
    \'coordinates\',
    \'population\         


        
相关标签:
6条回答
  • 2020-12-04 19:02

    On Ubuntu 14.04 LTS versions of python2.7 and python3.4 the __dict__ property worked as expected. The _asdict method also worked, but I'm inclined to use the standards-defined, uniform, property api instead of the localized non-uniform 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
    

    Seeing as dict is the semantic way to get a dictionary representing soemthing, (at least to the best of my knowledge).


    It would be nice to accumulate a table of major python versions and platforms and their support for __dict__, currently I only have one platform version and two python versions as posted above.

    | 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     |
    
    0 讨论(0)
  • 2020-12-04 19:06

    Python 3. Allocate any field to the dictionary as the required index for the dictionary, I used '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}
    
    0 讨论(0)
  • 2020-12-04 19:07

    TL;DR: there's a method _asdict provided for this.

    Here is a demonstration of the usage:

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

    This is a documented method of namedtuples, i.e. unlike the usual convention in python the leading underscore on the method name isn't there to discourage use. Along with the other methods added to namedtuples, _make, _replace, _source, _fields, it has the underscore only to try and prevent conflicts with possible field names.


    Note: For some 2.7.5 < python version < 3.5.0 code out in the wild, you might see this version:

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

    For a while the documentation had mentioned that _asdict was obsolete (see here), and suggested to use the built-in method vars. That advice is now outdated; in order to fix a bug related to subclassing, the __dict__ property which was present on namedtuples has again been removed by this commit.

    0 讨论(0)
  • 2020-12-04 19:10

    Case #1: one dimension 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" 
    

    Case #2: Two dimension tuple
    Example: DICT_ROLES[961] # will show 'Back-End Programmer'

    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()
    
    0 讨论(0)
  • 2020-12-04 19:18

    if no _asdict(), you can use this way:

    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
    
    0 讨论(0)
  • 2020-12-04 19:27

    There's a built in method on namedtuple instances for this, _asdict.

    As discussed in the comments, on some versions vars() will also do it, but it's apparently highly dependent on build details, whereas _asdict should be reliable. In some versions _asdict was marked as deprecated, but comments indicate that this is no longer the case as of 3.4.

    0 讨论(0)
提交回复
热议问题