2011-10-13 19 views
21

muszę zrobić coś, co jest równoważne funkcjonalnie to:Czy funkcje obiektu wywołania funkcji mapy Pythona mogą być używane?

for foo in foos: 
    bar = foo.get_bar() 
    # Do something with bar 

Moim pierwszym odruchem było wykorzystanie map, ale to nie działa:

for bar in map(get_bar, foos): 
    # Do something with bar 

Czy to, co staram się osiągnąć możliwe z map? Czy zamiast tego muszę użyć funkcji sprawdzania list? Jaki jest najbardziej idiom Pythonica?

+3

Dlaczego po prostu nie skorzystasz ze sprawdzania listy? – agf

Odpowiedz

35

albo z lambda:

for bar in map(lambda foo: foo.get_bar(), foos): 

lub methodcaller:

import operator 
get_bar = operator.methodcaller('get_bar') 
for bar in map(get_bar, foos): 

lub wyrażenia generatora:

for bar in (foo.get_bar() for foo in foos): 
+8

W odwrotnej kolejności jak są one Pythoniczne. – agf

+12

Ponadto, 'map (Foo.get_bar, foos)' gdzie 'Foo' jest klasą obiektów w' foos'. – agf

+0

Zdecydowałem się pójść z lambdą, odkąd zdałem sobie sprawę, że muszę zrobić tę transformację kilka miejsc w kodzie, a 'Bar's musi być usztywniony i pisany małymi literami. :) –

7

Chcesz operator.methodcaller(). Lub, oczywiście, spis treści lub generatora.

+0

Domyślam się, że w nowych wersjach Pythona preferowane są listy, prawda? Z przyjemnością przyjmuję twoją odpowiedź, jeśli zaktualizujesz ją, dodając przykładowy kod za pomocą LC dla mojego przykładu. :) –

+0

@JoshGlover "nowsze wersje Pythona"? Wracają do co najmniej 2,3. – agf

+0

Zrozumienia list zostały dodane w Pythonie 2.0. –

1

Zmodyfikowany kod działa:

for bar in map(lambda f: f.get_bar(), foos): 
# Do something with bar 

Tutaj można podać funkcję lambda. Po prostu dostarczenie get_bar nie działa, ponieważ jest dostępne tylko poprzez instancję klasy (f.get_bar()), nigdy samo przez się.

1

Można użyć lambda

for bar in map(lambda foo: foo.get_bar(), foos): 
    # Do something with bar 
1

myślę najczystszym sposobem jest zaniechaniu for -loop całkowicie i użyć wyrażeń listowych:

bars = [foo.get_bar() for foo in foos] 

Ta odpowiedź jest zbliżony do innego odpowiedzi, ale różni się tym, że lista jest rzeczywiście zwracana i nie jest używana w kolejnej pętli. Zależnie od tego, co zrobisz z bars, możesz użyć do tego celu listy zrozumiałej.

Nie sądzę, że funkcja map z lambdas jest szczególnie czytelna, poza obciążeniem dla map jest znaczna.

Powiązane problemy