2012-04-25 18 views
8

Dada la siguiente función f con dos argumentos, ¿cuál es la forma estándar de aplicar el mapa a solo x?Aplicar el mapa para el argumento parcial

def f (x,y): 
    print x,y 

Más específicamente, me gustaría realizar la siguiente operación con el mapa en una línea.

list=[1,2,3] 
fixed=10 
for s in list: 
    f(s,fixed) 

Una forma de hacerlo es:

import functools 
map(functools.partial(lambda x,y:f(y,x),fixed),list) 

Qué es una mejor manera?

Respuesta

14

En primer lugar, no hay necesidad de utilizar lambda y parcial - que son alternativas:

map(lambda x:f(x,fixed),srclist) 

En segundo lugar, usted podría obligar a la segunda discusión con partial, siempre y cuando se conoce el nombre del argumento:

map(functools.partial(f,y=fixed),srclist) 

otra alternativa es utilizar una lista de comprensión:

[f(x, fixed) for x in srclist] 
+1

¿Puede comentar cómo se compara el rendimiento de estos tres métodos? – chase

+1

@chase Bien, el último no implica ninguna aplicación parcial real, por lo que evita cualquier sobrecarga. En cuanto a los otros dos, no puedo decirlo. Este tipo de micro-optimización no debería ocurrir hasta que identifiques un punto de acceso de todos modos. – Marcin

+0

Generalmente estoy de acuerdo. Aunque de vez en cuando uno busca las preguntas SO de 2 años cuando encuentran un punto clave;) Debería ser lo suficientemente fácil para hacer un perfil, aunque personalmente prefiero la última solución para mayor claridad. – chase

5
map(lambda x: f(fixed,x), thelist) 

O no use map() en absoluto, use las listas de comprensión en su lugar.

[f(fixed, x) for x in thelist] 

PD: no utilice list como nombre de variable, que es un importante incorporado en el nombre (el tipo de lista).

1

¿Qué hay de malo en:

def add(x, y): 
    return x + y 

l = [1, 2, 3] 

from functools import partial 
plus10 = map(partial(add, y=10), l) 
print plus10 

## [11, 12, 13] 
+0

Es ilegible (¿y pensé que Python se explicaba a sí mismo?). Los ejemplos de comprensión de listas son mucho más legibles. – Ingo

+0

@Ingo: claro, excepto que OP no dijo nada sobre las comprensiones. – georg

5

Dada la siguiente función f con dos argumentos, ¿cuál es la forma estándar para aplicar Mapa solamente x?

una pequeña discusión sobre el pellejo y la aplicación parcial

En términos de PF, su función es f"uncurried" - si bien conceptualmente toma dos argumentos, que están agrupados en una sola estructura del producto. En Python, todo está desordenado, todo el tiempo. Tienes que dar todos los argumentos a la vez, o ninguno de ellos.

Para solucionar esto, hay varios trucos, pero conceptualmente solo quieres "curry" la función. Es decir, transforma f(x,y) en f(x) que devuelve una nueva función g(y).

En las lenguas que están al curry por defecto, se puede escribir esta traducción fácilmente como:

-- curry: take a function from (x,y) to one from x to a function from y to z 
curry :: ((x,y) -> z) -> (x -> y -> z) 
curry f x y  = f (x, y) 

Así curry quita el curry f y sus argumentos de productos, por separado, y aplica los argumentos una vez que están todos disponibles. Lo contrario también es bastante fácil:

uncurry :: (x -> y -> z) -> ((x,y) -> z) 
uncurry f (x,y) = f x y 

¿Cómo se relaciona esto con la aplicación parcial?

  • Currying realiza una función que toma una estructura de (n -producto) argumento, y devuelve una nueva función de tomar n argumentos.
  • Aplicación parcial toma una función de n argumentos y las aplica a k argumentos, produciendo una función de n-k argumentos restantes.

En un idioma no utilizado, cada uno de los argumentos se puede aplicar sucesivamente (por ejemplo, parcialmente, con respecto a la aridad de la función). En un lenguaje al curry, debe jugar algunos trucos para deshacer la función primero, como en los ejemplos anteriores.

Creo que es más flexible estar en un entorno currículo por defecto, ya que la aplicación parcial es gratuita. En dicho entorno, es común encadenar funciones que modify a data structure into a pipeline. P.ej. una tubería de modificaciones enteros:

(+1) . (*2) . (^3) $ 7 

es sólo una cadena de aplicadas parcialmente, funciones uncurried, integrado, operando cada uno en la salida de la función anterior. Esto puede ser bueno, ya que separa las preocupaciones visualmente.

Cuestiones relacionadas