2011-10-13 12 views
21

tengo que hacer algo que es funcionalmente equivalente a esto:¿Puede la función de mapa de Python llamar a las funciones miembro de objeto?

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

Mi primer instinto fue utilizar map, pero esto no funcionó:

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

es lo que estoy tratando de lograr posible con map? ¿Debo usar una lista de comprensión en su lugar? ¿Cuál es el modismo más pitónico para esto?

+3

¿Por qué no usarías simplemente una lista de comprensión? – agf

Respuesta

35

ya sea con lambda:

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

o con methodcaller:

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

o con una expresión generador:

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

En orden inverso de cuán pitónicos son. – agf

+12

También, 'map (Foo.get_bar, foos)' donde 'Foo' es la clase de los objetos en' foos'. – agf

+0

Decidí ir con el lambda ya que me di cuenta de que necesitaba hacer esta transformación un par de lugares en el código, y 'Bar's necesitaba ser codificado y minúscula. :) –

7

Quiere operator.methodcaller(). O, por supuesto, una lista o comprensión del generador.

+0

Supongo que las listas de comprensión son preferidas en las versiones más nuevas de Python, ¿verdad? Estaré encantado de aceptar su respuesta si la actualiza para incluir código de muestra usando un LC para mi ejemplo. :) –

+0

@JoshGlover "versiones más nuevas de Python"? Vuelven al menos a 2,3. – agf

+0

Se agregaron comprensiones de listas en Python 2.0. –

1

Este código modificado funcionará:

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

Proporciona la función lambda aquí. El simple hecho de proporcionar get_bar no funciona porque solo se puede acceder a través de una instancia de la clase (f.get_bar()), nunca por sí mismo.

1

Puede utilizar lambda

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

Creo que la forma más limpia es renunciar a la for completamente -loop y utilizar una lista por comprensión:

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

Esta respuesta es cerca de alguna otra respuestas, pero difiere en que la lista realmente se devuelve y no se utiliza en el ciclo siguiente. Dependiendo de lo que haga con bars, es posible que pueda usar una lista de comprensión allí.

No creo que la función map con lambdas sea particularmente legible, además la sobrecarga para map es considerable.

Cuestiones relacionadas