2012-07-09 13 views
6

map e filter sono spesso intercambiabili con list comprehension, ma reduce non è così facilmente scambiato fuori come map e filter (e oltre, in alcuni casi, io preferisco ancora la sintassi funzionale in ogni caso). Quando è necessario operare sugli argomenti stessi, tuttavia, mi trovo a passare attraverso la ginnastica sintattica e alla fine devo scrivere intere funzioni per mantenere la leggibilità.Puoi applicare un'operazione direttamente agli argomenti all'interno di map/reduce/filter?

Userò map per mantenere il test dell'unità di illustrazione semplice, ma tieni presente che i casi di utilizzo nella vita reale potrebbero essere più difficili da esprimere come una lista di comprensione.

Ho trovato due modi disordinati per farlo, ma nulla che avrei mai effettivamente utilizzato.

[afunc(*i) for i in aniter] == map(afunc, *zip(*aniter)) 
[afunc(*i) for i in aniter] == map(lambda i: apply(afunc, i), aniter) 

Esiste un modo conciso ed elegante per esprimere il lato destro di queste espressioni?

risposta

11

Dai un'occhiata allo itertools per strumenti che ti semplificheranno la vita.

Ad esempio, il codice che hai postato è già disponibile come itertools.starmap.

itertools.starmap(afunc, aniter) 

Dalla documentazione:

Crea un iteratore che calcola la funzione usando argomenti ottenuti da iterable. Usato invece di imap() quando i parametri degli argomenti sono già raggruppati in tuple da un singolo iterabile (i dati sono stati "pre-zippati"). La differenza tra imap() e starmap() è parallela alla distinzione tra funzione (a, b) e funzione (* c). Equivalente a:

def starmap(function, iterable): 
    # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 
    for args in iterable: 
     yield function(*args) 

Ci sono anche tonnellate rispetto ad altre chicche nascoste in itertools, quindi vi consiglio di leggere attraverso la documentazione per vedere se c'è qualcos'altro lì che è possibile utilizzare. La sezione recipes mostra anche come utilizzare le funzioni disponibili in itertools per risolvere una serie di problemi. Anche se non riesci a trovare una ricetta che risolva i tuoi requisiti esatti, è probabile che tu possa utilizzare alcune delle idee dimostrate come fonte di ispirazione.

+0

Bello, io uso itertools tutto il tempo, ma per qualche motivo non mi è venuto in mente di guardare lì per questo. – kojiro

+0

+1 per il link delle eccellenti ricette! Non l'ho mai notato – Kos

Problemi correlati