Reputation: 1481
I have an uniform list of objects in python:
class myClass(object):
def __init__(self, attr):
self.attr = attr
self.other = None
objs = [myClass (i) for i in range(10)]
Now I want to extract a list with some attribute of that class (let's say attr
), in order to pass it to some function (for plotting that data for example)
What is the pythonic way of doing the following:
attr = [o.attr for o in objs]
Maybe derive list and add a method to it, so I can use some idiom like
objs.getattribute("attr")
?
Upvotes: 121
Views: 147147
Reputation: 23081
Another way could be to map getattr()
on objs
list.
# for a generator
from itertools import repeat
attrs = map(getattr, objs, repeat('attr'))
# or even without itertools
attrs = map(getattr, objs, ['attr']*len(objs))
# for a list
attrs = list(map(getattr, objs, repeat('attr')))
A nice thing about getattr
is that a default value can be returned if no such attribute exist. For example, the below line returns 'NA'
if attr
is not defined in an object.
attrs = [getattr(o, 'attr', 'NA') for o in objs]
If multiple attributes need to be fetched, operator.attrgetter
could be useful.
from operator import attrgetter
attrs = list(map(attrgetter('attr', 'other'), objs))
N.B. itertools
and operator
are in the standard library.
Upvotes: 2
Reputation: 16624
You can also write:
attr=(o.attr for o in objsm)
This way you get a generator that conserves memory. For more benefits look at Generator Expressions.
Upvotes: 117
Reputation: 76683
attrs = [o.attr for o in objs]
was the right code for making a list like the one you describe. Don't try to subclass list
for this. Is there something you did not like about that snippet?
Upvotes: 135