0

The functional map(func,iterable) could be easily applied to normal functions, but if I want to apply the a_method to a list of instances, how can I do it? I know list comprehensions can do this in a snap, but still want to see if a functional way exist and also feels pythonic.

class cls(object):
    def __init__(self,val):
        self.val=val
    def clstest(self,val):
        return self.val==val
a=cls(9)
b=cls(18)
c=cls(19)
lst=[a,b,c]

Then the following works:list(map(repr,lst)) returns

['<__main__.Cls object at 0x00000000070EDB70>',
 '<__main__.Cls object at 0x00000000070EDBE0>',
 '<__main__.Cls object at 0x00000000070EDE80>']

, but list(map(clstest(10),lst)) will have error msg:

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-165-f10396f98b58> in <module>()
----> 1 list(map(clstest,lst))

NameError: name 'clstest' is not defined

Update: correct my mistake in defining the class. The error msg still remains.

1
  • First of all, def cls(object) defines a function called cls that takes one parameter called object. If you want a class that inherits from object, you should go with class cls(object). Secondly, try out cls.clstest in your map Commented Jan 23, 2014 at 20:38

4 Answers 4

1

Another possibility (with help from this answer)

class cls(object):
    def __init__(self,val):
        self.val=val
    def clstest(self,val):
        return self.val==val
a=cls(9)
b=cls(10)
c=cls(19)
lst=[a,b,c]
# use functools.partial
from functools import partial
list(map(partial(cls.clstest,val=10),lst))
Sign up to request clarification or add additional context in comments.

2 Comments

partial is useful when you save references, in this case it's a waste of resources
A partial object is just a wrapper, like a lambda, but with more flexible semantics.
1

Is this what you are looking for?

import operator
lst = [ cls(9), cls(18), cls(19) ]
x = operator.methodcaller('clstest', 10)
map( x, lst )

The methodcaller function creates a callable object that invokes a named method on its argument, so for example x(lst[0]) is the same as lst[0].clstest(10).

1 Comment

This will work, but put an '`' to call the method by name seems not very 'smooth' (pythonic?).
0

The very first word in your code should be class, not def. Accepted practices in Python is giving ClassNames (cls is usually used for class methods). And you indents need fixing.

Here is untetsted full answer

class MyClass(object):
    def __init__(self,val):
        self.val=val
    def clstest(self,val):
        return self.val==val

objects = [MyClass(v) for v in (9, 18,19)]
map(lambda o: o.clstest(10), objects)

The answer is - yes, you can

9 Comments

This is very true (and probably just a typo copying into SO), but I'm not convinced it answers OP's question.
@mhlester, I did not compete for answer - you already provided one. Did you try yours - has it worked with definitions as they are?
(downvote wasn't me btw). If you're not answering the question, this should be a comment, not an answer
You did neither - with wrong definitions your answer is useless
@NathaneilCapital, because clstest is defined within a boundary of the class. See my edited answer
|
0

You should wrap the function in a lambda:

list(map(lambda instance: instance.clstest(10), lst))

Or as you mentioned, as a list comprehension:

[instance.clstest(10) for instance in lst]

Also, this line makes me cry: lst=list([a,b,c]) should just be lst = [a,b,c]

Comments

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.