2010-11-20 7 views
15

¿Hay Python idiomático y/o elegante para comprimir y aplicando una lista de funciones sobre una lista de valores?Comprueba y aplica una lista de funciones sobre una lista de valores en Python

Por ejemplo, suponga que tiene una lista de funciones:

functions = [int, unicode, float, lambda x: '~' + x + '~'] 

y una lista de valores:

values = ['33', '\xc3\xa4', '3.14', 'flange'] 

¿Hay una manera de aplicar la función i por valor de ITH y el retorno una lista de la misma longitud de los valores transformados, mientras se evita esta lista fea de comprensión?

[functions[i](values[i]) for i in range(len(functions))] # <- ugly 

Lo que yo quiero es algo así como zip() + map() (zipmap()!) La lista de funciones con la lista de valores y tener las funciones pueden aplicar a sus valores apareados. Pensé que itertools podría ofrecer algo relevante, pero funciones como imap y starmap son para mapear una única función sobre una iterable, no una iterable de funciones sobre otra iterable.

+0

estoy inclinado a decir que la tarea que está deseando es un poco feo en sí, por lo que uno debe esperar que la aplicación sea - como tú lo juzgas, feo también. – msw

+2

@msw Creo que la tarea es bastante común: piense en transformar cadenas de bytes sin procesar a objetos de Python desde un archivo CSV o similar, de modo que la lista de funciones pueda provenir de una asignación de columnas que contenga otros metadatos como los datos de la columna, etc. –

+1

@msw: asómese dentro de una base de datos promedio y vea qué feo puede crecer una base de datos cuando nadie se molesta en escribir un código feo para validarlo. –

Respuesta

16

Estas soluciones parecen demasiado complicadas: map ya cremalleras sus argumentos:

map(lambda x,y:x(y), functions, values) 

O, si lo prefiere la versión iterador:

from itertools import imap 
imap(lambda x,y:x(y), functions, values) 
20
[x(y) for x, y in zip(functions, values)] 
+0

Para ser honesto, esperaba una solución sin lista basada en la comprensión, sin importar cuán elegante, y sin dudas la suya, estaba esperando una solución de aplicación funcional, preferiblemente de la biblioteca estándar. Pero el tuyo es práctico, conciso, y no feo :) –

+0

Correcto - Supongo que quise decir, una aplicación de función pura en lugar de sintaxis. Pero punto tomado :) –

+2

@ Paul Smith, una de las razones por las que este tipo de cosas no necesita ser cubierto por la biblioteca estándar es que Python tiene listas de comprensión. Son una parte integral del idioma y se deben usar cuando corresponda. Son apropiados aquí. – aaronasterling

4

Una de las hermosas características de la encapsulación funcional es que pueden ocultar la fealdad.

Si necesita zipmap, definirlo:

def zipmap(values, functions): 
    return [functions[i](values[i]) for i in range(
     len(functions))] 
1

Código que está diseñado para funcionar con fuerza w Ould hacer esto en un bucle para que pudiera proporcionar el informe de errores significativos:

for i in xrange(num_columns): 
    try: 
     outrow.append(functions[i](input_values[i]) 
    except (ValueError, EtcetcError) as e: 
     self.do_error_reporting(row_number, i, input_value[i], e) 
     outrow.append(None) 
Cuestiones relacionadas