2013-08-01 13 views
6

Próbuję wywołać object.method() na liście obiektów.Jak używać map() do wywoływania metod klasy na liście obiektów

Próbowałem tego, ale nie może zmusić go do pracy prawidłowo

newList = map(method, objectList) 

pojawia się błąd method is not defined ale wiem, że to dlatego, że jest to metoda klasy, a nie lokalny funkcja.

Czy jest jakiś sposób, aby to zrobić z map() lub podobną wbudowaną funkcją? Czy będę musiał użyć zrozumienia generatora/listy?

edytuj Czy możesz również wyjaśnić zalety lub przeciwstawić swoje rozwiązanie do korzystania z tej listy?

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

Odpowiedz

6

newList = map(method, objectList) będzie wywoływać method(object) na każdym object w objectlist.

Sposobem na to na mapie zrobić wymagałoby funkcję lambda, np

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

Lista rozumienie może być marginalnie szybciej, widząc, jak nie będzie potrzebował lambda, która posiada pewne napowietrznych (omówione nieco here).

+2

Mały dodatek: jeśli chcesz mieć możliwość używania dowolnej starej 'metody' i dowolnej starej' objectList': 'new_lister = metoda lambda, objectList: map (lambda obj: obj.method(), objectList)'. Teraz możesz zrobić "newList = new_lister (foo_method, list_of_foos)" itd. – 2rs2ts

+0

Czy możesz wyjaśnić użycie funkcji lambda?Myślałem, że mapa przekazała elementy listy jako parametry funkcji. W jaki sposób funkcja lambda przyjmuje obiekty jako parametry? – Stephan

+0

'lambda obj: obj.method()' jest odpowiednikiem: 'def foo (obj): obj.method'. Tak więc 'map' faktycznie przekazuje elementy listy jako parametry. Każdy element zostanie przekazany jako "obj", pierwszy argument lambda. Ma sens? –

3

Jeśli na liście znajdują się wszystkie wystąpienia tej samej klasy, można poprzedzić nazwę metody nazwą klasy.

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) 

Wynik:

[4, 8, 15] 

Można to również zrobić, jeśli elementy listy są podklasy określonej klasy. Jednak nadal wywoła określoną implementację metody, nawet jeśli ta metoda zostanie nadpisana w podklasie. Przykład:

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

Nie powiedzie się, jeśli na liście znajdują się obiekty, które nie są co najmniej podklasami. –

+0

Tak, będę edytować w zastrzeżeniu do tego efektu. – Kevin

+0

czy ma to coś wspólnego z 'map()' przy użyciu argumentu 'self', ponieważ mapa przekazuje drugi argument jako parametr do funkcji zdefiniowanej w pierwszym argumencie? Nigdy nie znalazłem przypadku, w którym musiałbym zrozumieć ten argument. – Stephan

10

Zastosowanie operator.methodcaller():

from operator import methodcaller 

map(methodcaller('methodname'), object_list) 

Działa to dla każdej listy obiektów, które wszystkie mają taką samą metodę (według nazwy); nie ma znaczenia, czy na liście znajdują się różne typy.

+4

Jezu, czy pamiętasz wszystkie przydatne funkcje wbudowane z góry głowy? – Stephan

Powiązane problemy