Python: Convert list of tuples into a list of objects?

Viewed 3948

If I have a list of tuples like the following:

Data = [
        #   OP,  FLAG,   IDENT,  NAME
        ( Op.GA, Flag.GA, "GA", "Asset" ),
        ( Op.LP, Flag.LP, "LP", "Low" ),
        ( Op.HP, Flag.HP, "HP", "High" ),
        ( Op.CU, Flag.CU, "CU", "Custom" ),
]

Is there a clever way to convert this into a list of objects so that it would be like I did the following instead:

Objects = [
        #       OP,    FLAG,    IDENT,  NAME
        OBJECT( Op.GA, Flag.GA, "GA", "Asset" ),
        OBJECT( Op.LP, Flag.LP, "LP", "Low" ),
        OBJECT( Op.HP, Flag.HP, "HP", "High" ),
        OBJECT( Op.CU, Flag.CU, "CU", "Custom" ),
]

I'm hoping for something like Objects = create( OBJECT, Data )

I think I managed to figure out how to convert one element at a time using a loop and tuple unpacking (new to me). So essentially, iterate the tuple list and construct one object at a time as I append them to a second list. Is that the best way to handle this?

The reason: I'm trying to allow external code to send enum-like properties as a list of tuples, then use that to generate a list of class instances to represent enum-like data. The only reason I need classes at all is to allow external code to reference the data using named members, such as enum_ref.Ident (instead of enum_ref[2]). But maybe there is a better way to handle this type of situation?

Really appreciate any advice. I'm inexperienced with Python, so you can safely assume I don't know all of the basics.

Edit: Here is the definition of OBJECT. It is a custom class that can be changed however I need in order to make this work:

class OBJECT:

    # construct / attributes
    def __init__(self,index,value,ident,name):

        self.Index = index  # enum index or type-index
        self.Value = value  # actual value of the entry (any type)
        self.Ident = ident  # identifier string (for Blender and searching)
        self.Name = name    # display name
3 Answers

I think you answered this to yourself already, instead of using a loop you can go with a list comprehension:

Objects = [OBJECT(*x) for x in Data]

Although I see the tuples in your Data are missing one parameter for OBJECT construction (the one corresponding to desc).

I think namedtuple is a nice minimal Python class for convenient access of attributes by name. Here how it would look like

from collections import namedtuple
Data = [
        #   OP,  FLAG,   IDENT,  NAME
        ( "Op.GA", "Flag.GA", "GA", "Asset" ),
        ( "Op.LP", "Flag.LP", "LP", "Low" ),
        ( "Op.HP", "Flag.HP", "HP", "High" ),
        ( "Op.CU", "Flag.CU", "CU", "Custom" ),
]

Object = namedtuple("Object", "OP FLAG IDENT NAME")
objects = [Object(*t) for t in Data]

After that:

>>> objects[0].IDENT
GA

PS substituted your Op.GA for mere strings for the sake of instantly working example.

You can use a different approach with the builtin map function like this:

list_of_objects = list(map(lambda tpl: OBJECT(*tpl), Data))

Beaware, map only produces an Iterator the list call can not be omitted.

Related