2015-05-08 7 views
5

Si consideri il seguente codice:Si può usare i derivati ​​della comprensione delle liste nei suoi metodi?

a = [... for i in input] 
i = a.index(f(a)) 

Mi chiedo se potrei essere in grado di fare un one-liner. Prova ovvia è:

i = [... for i in input].index(f([... for i in input])) 

Ma questa soluzione richiede che venga generata una lista due volte. non così ovvia prova è:

i = [ a.index(f(a)) for a in [[... for i in input],] ] 

che fa il trucco, ma rende il codice davvero strano.

Questo mi porta all'idea che, probabilmente, non v'è possibilità di utilizzare in qualche modo la lista, generato dalla lista di comprensione, nella sua chiamata di metodo. Qualcosa come (non funziona, ovviamente):

i = [... for i in input].index(f(_)) 
# or 
i = [... for i in input].index(f(self)) 

Può essere fatto?

+5

Perché vuoi eliminare la leggibilità? :) –

+3

Cosa fa f()? Vuoi semplicemente ottenere l'indice di un determinato elemento della lista? – ODiogoSilva

+1

Puoi creare un lambda e chiamarlo immediatamente con la tua comprensione: 'i = (lambda x: x.index (f (x)) ([... per i in input])' Ma questa è un'eresia. 'Nome un input iterabile, che maschera la funzione di input incorporata – Shashank

risposta

2

Un modo che evita di ripetere la lista-di comprensione è quello di creare una funzione anonima e chiamando direttamente (non testato):

i = (lambda a: a.index(f(a)))([... for i in input]) 

Questo è ancora un po 'brutto, però. Il tuo primo esempio che ha utilizzato la variabile temporanea a è molto più chiaro. Scrivere un one-liner come esercizio è divertente, ma di solito non è il modo migliore per scrivere codice mantenibile.

6

Come si esegue un'attività di ricorsione, in base a ciò che la funzione fa è possibile combinare la propria funzione con una comprensione di lista o un'espressione di generatore.

per esempio si consideri il seguente codice:

>>> f=lambda x:next(i for i in x if i.startswith('a')) 
>>> 
>>> a=['df','sr','t','aaf','ar','trf'] 
>>> a.index(f(a)) 
3 

Potete mescolare come seguire con enumerate:

>>> next(i for i,j in enumerate(a) if j.startswith('a')) 
3 

Così il suo tutto, sulla base di funzione che come si può mettere la sua struttura all'interno una list comprehension o un'espressione di generatore, quindi applicare alcune modifiche su di esso e utilizzare gli strumenti python in base alle proprie esigenze (in questo caso è stato utilizzato enumerate).

+0

per quanto posso vedere - la tua soluzione funziona solo per indicizzazione semplice compiti; tuttavia non è applicabile in generale. L'esempio più semplice a cui riesco a pensare è if f = min (mylist), così potremmo recuperare l'indice dell'elemento minimo dal generatore. Non mi sembra ovvio, come la soluzione potrebbe essere utilizzata per questo caso. E anche, come ho detto in commento più in alto - il mio interesse è se ci sia una variabile incorporata come "_", solo che uno potrebbe permettermi di accedere ai risultati non dell'espressione precedente, ma del precedente termine calcolato all'interno dell'espressione. –