-2

I have a list of lists of 2-element lists, e.g.:

[[[a, b], [c, d], [e, f]], [[g, h], [i, j], [k, l]]] 

and I want to create a list of objects with attributes from the two-element lists, like this:

[(obj.a = b, obj.c=d, obj.e=f), (obj.g=h, obj.i=j, obj.k=l)]

I tried many ways, but seems I really don't know how, creating an object like a = object() and setting attrs via object.__setattr__ didn't work for me.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Viker
  • 21
  • 1
  • 4
  • 3
    What does *"didn't work for me"* mean, exactly? Where is your code, and what precisely is wrong with it? Does your list actually (eventually) contain strings, or some other objects? – jonrsharpe Oct 13 '14 at 13:49
  • Yes a big reason why this question is not answerable in its current form is that you did not follow the guideline of posting code that you're actually attempting to run – ErlVolton Oct 13 '14 at 14:02
  • You're right, both of You, but let's say after 3 hours of rewriting from many angles, i'm not sure which try i should passt exactly... – Viker Oct 14 '14 at 07:02

2 Answers2

2

You can't set arbitrary attributes on object instances:

>>> a = object()
>>> a.b = 'c'

Traceback (most recent call last):
  File "<pyshell#56>", line 1, in <module>
    a.b = 'c'
AttributeError: 'object' object has no attribute 'b'

Howver, you can create a Generic class that will allow you to:

class Generic(object):
    pass

Then, assuming your list contains string pairs:

l = [[['a', 'b'], ['c', 'd'], ['e', 'f']], 
     [['g', 'h'], ['i', 'j'], ['k', 'l']]]

you can iterate over it as follows:

out = []
for ll in l:
    obj = Generic()
    for attr, val in ll:
        setattr(obj, attr, val)
    out.append(obj)

Alternatively, you can use the three-argument form of type to create arbitrary classes, then create instances of those:

out = [type("Generic", (object,), dict(ll))() for ll in l]

Note that e.g.

>>> dict(l[0])
{'a': 'b', 'c': 'd', 'e': 'f'}

Finally, if you have an actual (not generic) object that takes e.g. a, c, e as arguments to __init__:

class Actual(object):
    def __init__(self, a, c, e):
        self.a = a
        self.c = c
        self.e = e

You can use dictionary unpacking to create an instance from the sub-list e.g. l[0]:

obj = Actual(**dict(l[0]))
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • This was exactly what i had in mind, after few hours i made "brutal" assigment (created object, by some inner cycles takeout data from "inside" of inner list and assigned it manualy), but that iteration about pairs is exactly what i needed. Thank You – Viker Oct 14 '14 at 07:04
0

When in doubt, use a dict:

>>> A=[[["a", "b"], ["c", "d"], ["e", "f"]], [["g", "h"], ["i", "j"], ["k", "l"]]] 
>>> [x for x in A]
[[['a', 'b'], ['c', 'd'], ['e', 'f']], [['g', 'h'], ['i', 'j'], ['k', 'l']]]
>>> B = [dict(x) for x in A]
>>> repr(B)
[{'a': 'b', 'c': 'd', 'e': 'f'}, {'i': 'j', 'k': 'l', 'g': 'h'}]
vz0
  • 32,345
  • 7
  • 44
  • 77
  • I'm not realy sure about mechanism you are using here, can you please clarify a little ? I was trying to make dict from inner list, but i always get error like : need #0 length of 2 but 5 is provided, which i'm unsure what it means when i always have pairs inside inner list (checked x times by pprint on every step) – Viker Oct 14 '14 at 07:05