Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use map() to call class methods on a list of objects

I am trying to call object.method() on a list of objects.

I have tried this but can't get it to work properly

newList = map(method, objectList)

I get the error method is not defined but I know that is because it is a class method and not a local function.

Is there a way to do this with map(), or a similar built in function? Or will I have to use a generator/list comprehension?

edit Could you also explain the advantages or contrast your solution to using this list comprehension?

newList = [object.method() for object in objectList]
like image 517
Stephan Avatar asked Aug 01 '13 15:08

Stephan


People also ask

How do I map an object to a list?

Use the list() class to convert a map object to a list, e.g. new_list = list(map(my_fuc, my_list)) . The list class takes an iterable (such as a map object) as an argument and returns a list object. Copied! We passed a map object to the list() class to convert it to a list.

How do you map a class in Python?

Python map() function map() function returns a map object(which is an iterator) of the results after applying the given function to each item of a given iterable (list, tuple etc.) Parameters : fun : It is a function to which map passes each element of given iterable. iter : It is a iterable which is to be mapped.

Can you call a class method on an object?

classmethod() methods are bound to a class rather than an object. Class methods can be called by both class and object. These methods can be called with a class or with an object.

What does the map () help with?

map() is useful when you need to apply a transformation function to each item in an iterable and transform them into a new iterable. map() is one of the tools that support a functional programming style in Python.


3 Answers

newList = map(method, objectList) would call method(object) on each object in objectlist.

The way to do this with map would require a lambda function, e.g.:

map(lambda obj: obj.method(), objectlist)

A list comprehension might be marginally faster, seeing as you wouldn't need a lambda, which has some overhead (discussed a bit here).

like image 192
Charles Marsh Avatar answered Oct 17 '22 18:10

Charles Marsh


Use operator.methodcaller():

from operator import methodcaller

map(methodcaller('methodname'), object_list)

This works for any list of objects that all have the same method (by name); it doesn't matter if there are different types in the list.

like image 28
Martijn Pieters Avatar answered Oct 17 '22 17:10

Martijn Pieters


If the contents of the list are all instances of the same class, you can prefix the method name with the class name.

class Fred:
    def __init__(self, val):
        self.val = val
    def frob(self):
        return self.val

freds = [Fred(4), Fred(8), Fred(15)]
print map(Fred.frob, freds)

Result:

[4, 8, 15]

This can also be done if the elements of the list are subclasses of the specified class. However, it will still call the specified implementation of the method, even if that method is overridden in the subclass. Example:

class Fred:
    def __init__(self, val):
        self.val = val
    def frob(self):
        return self.val

class Barney(Fred):
    def frob(self):
        return self.val * 2

freds = [Fred(4), Barney(8), Barney(15)]
#You might expect the barneys to return twice their val. ex. [4, 16, 30]
#but the actual output is [4, 8, 15]
print map(Fred.frob, freds)
like image 6
Kevin Avatar answered Oct 17 '22 17:10

Kevin