【问题标题】:can I map a "bound" method to a list of instances using map() in python?我可以在 python 中使用 map() 将“绑定”方法映射到实例列表吗?
【发布时间】:2014-01-23 20:34:52
【问题描述】:

函数map(func,iterable) 可以很容易地应用于普通函数,但是如果我想将a_method 应用于实例列表,我该怎么做?我知道列表推导可以很快做到这一点,但仍然想看看是否存在一种功能性的方式并且感觉像 Python 一样。

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]

然后以下工作:list(map(repr,lst))返回

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

,但list(map(clstest(10),lst)) 会有错误信息:

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

NameError: name 'clstest' is not defined

更新:更正我在定义类时的错误。错误消息仍然存在。

【问题讨论】:

  • 首先,def cls(object) 定义了一个名为cls 的函数,它接受一个名为object 的参数。如果你想要一个继承自object 的类,你应该使用class cls(object)。其次,在您的map 中尝试cls.clstest

标签: python functional-programming


【解决方案1】:

另一种可能性(在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))

【讨论】:

  • partial 在你保存引用的时候很有用,在这种情况下是浪费资源
  • partial 对象只是一个包装器,类似于 lambda,但语义更灵活。
【解决方案2】:

这是你要找的吗?

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

methodcaller 函数创建一个可调用对象,该对象调用其参数的命名方法,例如,x(lst[0]) 与 lst[0].clstest(10) 相同。

【讨论】:

  • 这行得通,但是放一个“`”来按名称调用方法似乎不是很“流畅”(pythonic?)。
【解决方案3】:

代码中的第一个单词应该是class,而不是def。 Python 中公认的做法是给出 ClassNames(cls 通常用于类方法)。你的缩进需要修复。

这是未经测试的完整答案

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)

答案是——是的,你可以

【讨论】:

  • 这是非常正确的(可能只是复制到 SO 中的错字),但我不相信它回答了 OP 的问题。
  • @mhlester,我没有竞争答案 - 你已经提供了一个。您是否尝试过您的 - 它是否适用于定义?
  • (顺便说一句,downvote 不是我)。如果您没有回答问题,这应该是评论,而不是答案
  • 你都没有 - 如果定义错误,你的答案是没用的
  • @NathaneilCapital,因为 clstest 是在类的边界内定义的。查看我编辑的答案
【解决方案4】:

您应该将函数包装在lambda:

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

或者正如你提到的,作为列表理解:

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

另外,这行让我哭了:lst=list([a,b,c]) 应该只是 lst = [a,b,c]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    相关资源
    最近更新 更多