1

How do I insert a list (or numpy array) containing attribute values into a list of objects (as shown below)?

class myClass(object):
    def __init__(self, attr):
        self.attr = attr
        self.other = None

objs = []
for i in range(10):
        objs.append(myClass(i))

attrs = [o.attr for o in objs]
print attrs
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[o.attr for o in objs] = range(10)
#SyntaxError: can't assign to list comprehension

This is the inverse problem to Extract list of attributes from list of objects in python.

1
  • 1
    As a note, your object creation could be a list comp too: objs = [myClass(i) for i in range(10)]. Commented Jul 4, 2013 at 11:56

2 Answers 2

3

I'd do something like this:

for i, o in enumerate(objs):
    o.attr = i

enumerate(objs) is sort of like zip(range(len(objs)), objs), so in case you actually want to take values from another sequence, you can:

for i, o in zip(sequence, objs):
    o.attr = i

For efficiency you might use itertools.izip there too.

Sign up to request clarification or add additional context in comments.

2 Comments

+1, I was just about to suggest you might want to give a more general solution, but then it appeared. As a tiny note on style, personally, I'd make sequence and obj appear the other way around in the call to zip() (and naturally swapping i, o to o, i to keep the functionality the same) as it would then mirror the order the objects are used in the code. Not important or changing any functionality, but I'd argue it's a little more readable.
@Lattyware: I'd swap the order in the zip too in practice, but here I kept it the same to avoid distracting from the point that the zip with range is equivalent to enumerate.
1

You can also use obj.__setattr__() within a list comprehension:

[o.__setattr__('attr',v) for o,v in zip(objs,range(10)[::-1])]
print [o.attr for o in objs]
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

6 Comments

-1 - this is reimplementing the wheel (setattr() exists), and it's using list comprehensions for side effects, which is a terrible idea.
Quite right, that was very sloppy of me. Here's a slightly less moronic answer that uses the built in __setattr__ method, although if it was me I'd still use John Zwinck's approach.
Why access the magic method directly? And this still uses a list comprehension for side effects.
I know it's ugly, just pointing out that it can actually be done in a list comprehension if you don't mind courting the hatred of other Python programmers :)
@Lattyware interesting to see the pythonic aversion towards 'comp lists for side effects', coming from Matlab I would have assumed that if a single code line is used to get the data, a single code line can be used to set the data... I guess this explains it stackoverflow.com/questions/5753597/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.