2013-08-01 6 views
6

オブジェクトのリストにobject.method()を呼び出そうとしています。map()を使用してオブジェクトのリストのクラスメソッドを呼び出す方法

私はこれを試してみましたが、私はエラーmethod is not definedを取得するが、私はそれがクラスメソッドではなくローカル関数であるので、それは知っている、それが適切に

newList = map(method, objectList) 

動作させることはできません。

map()などの組み込み関数でこれを行う方法はありますか?または、発電機/リストの理解度を使用する必要がありますか?

編集このリストの理解を使用して、利点や解決方法を説明することもできますか?

newList = [object.method() for object in objectList] 

答えて

6

newList = map(method, objectList)は、それぞれobjectのをobjectlistに呼び出します。

マップでこれを行う方法ラムダ関数を必要とするが、例えば:

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

リストの内包は、あなたには、いくつかのオーバーヘッドを持っているラムダが、必要ではないでしょうとして見て、わずか速くかもしれません(ビットhereを議論した)。

+2

少し追加:古い 'method'と古い' objectList':new_lister = lambdaメソッド、objectList:map(lambda obj:obj.method()、objectList) 'を使いたい場合。今度は 'newList = new_lister(foo_method、list_of_foos)'などを行うことができます。 – 2rs2ts

+0

ラムダ関数の使い方を説明できますか?私はマップが関数のパラメータとしてリストの要素を渡したと思った。ラムダ関数はどのようにオブジェクトをパラメータとして受け入れますか? – Stephan

+0

'lambda obj:obj.method()'は、 'def foo(obj):obj.method'と同じです。だから、 'map'は実際にはリストの要素をパラメータとして渡しています。各要素はラムダの最初の引数である 'obj'として渡されます。理にかなっている? –

3

リストの内容がすべて同じクラスのインスタンスである場合は、メソッド名の前にクラス名を付けることができます。

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) 

結果:

[4, 8, 15] 

これは、リストの要素が指定されたクラスのサブクラスである場合に行うことができます。ただし、サブクラスでそのメソッドがオーバーライドされている場合でも、メソッドの指定された実装が呼び出されます。例:

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) 
+2

少なくとも、サブクラスではないオブジェクトがリストに存在する場合、これは失敗します。 –

+0

はい、その旨の免責事項を編集します。 – Kevin

+0

mapは第2引数をパラメータとして第1引数で定義された関数に渡すので、これは 'self'引数を使って' map() 'と何か関係がありますか?私はその議論を理解しなければならないケースを見つけたことはありません。 – Stephan

10

使用operator.methodcaller()

from operator import methodcaller 

map(methodcaller('methodname'), object_list) 

これは、すべての(名前で)同じメソッドを持つオブジェクトの任意のリストのために働きます。リストに異なるタイプがあるかどうかは関係ありません。

+4

Jeez、頭の上からこれらの便利な機能をすべて覚えていますか? – Stephan

関連する問題