xpilot
xpilot

Reputation: 1019

Using map on methods in Python

I have some classes in Python:

class Class1:
    def method(self):
        return 1
class Class2:
    def method(self):
        return 2

and a list myList whose elements are all either instances of Class1 or Class2. I'd like to create a new list whose elements are the return values of method called on each element of myList. I have tried using a "virtual" base class

class Class0:
    def method(self):
        return 0
class Class1(Class0):
    def method(self):
        return 1
class Class2(Class0):
    def method(self):
        return 2

But if I try map(Class0.method, myList) I just get [0, 0, 0, ...]. I'm a bit new to Python, and I hear that "duck typing" is preferred to actual inheritance, so maybe this is the wrong approach. Of course, I can do

[myList[index].method() for index in xrange(len(myList))]

but I like the brevity of map. Is there a way to still use map for this?

Upvotes: 3

Views: 632

Answers (3)

Raymond Hettinger
Raymond Hettinger

Reputation: 226376

The operator.methodcaller tool is exactly what you're looking for:

map(methodcaller("method"), myList)

Alternatively you can use a list comprehension:

[obj.method() for obj in myList]

Upvotes: 4

Pavel Anossov
Pavel Anossov

Reputation: 62908

You can use

map(lambda e: e.method(), myList)

But I think this is better:

[e.method() for e in myList]

 

PS.: I don't think there is ever a need for range(len(collection)).

Upvotes: 4

Ned Batchelder
Ned Batchelder

Reputation: 375634

This is best:

[o.method() for o in myList]

Map seems to be favored by people pining for Haskell or Lisp, but Python has fine iterative structures you can use instead.

Upvotes: 3

Related Questions