Le comprensioni delle liste Python sono buone, ma quasi impossibili da eseguire il debug. Ragazzi avete dei buoni consigli/strumenti per il debugging?Suggerimenti per il debug della comprensione delle liste?
risposta
Se è abbastanza complicato che a prima vista non è ovvio, disimballarlo in più passaggi e/o cicli. È chiaramente troppo complicato e renderlo più esplicito è il modo più semplice per eseguire il debugging. Bonus aggiuntivo: ora puoi eseguire il debugger o aggiungere dichiarazioni di stampa!
suggerimento: utilizzare la comprensione dell'elenco per compiti semplici (1 o 2 livelli). In caso contrario, renderlo esplicito è meglio per la leggibilità.
In Haskell I utilizzando qualcosa di simile a:
def trcPV(prompt, value):
print ("%s%s" % (prompt, str(value)))
return value
xs = trcPV("xs=", [x for x in range(0,100) if trcPV("check=",(trcPV("x=",x) % 15) in [0,3,5])])
Utilizzare un debugger come pdb
a piedi attraverso o rompere la lista di comprensione in un completo ciclo for.
Le comprensioni degli elenchi haskell possono essere almeno (ed è ciò che fanno i compilatori) riscritte in termini di mappa, concat e filtro.
Quindi questo esempio Haskell:
[ x*x | x<-[1..25], even x]
funziona come:
map (\x-> x*x) (filter (even) [1..25])
mi aspetto identità simili continuerebbero a tenere per Python, così la decomposizione simile dovrebbe produrre codice equivalente in Python pure. Il codice equivalente dovrebbe risultare più facile da eseguire il debug (e funzionare in modo altrettanto efficiente).
Dipende dalla comprensione dell'elenco. È possibile spostare una parte del codice in un'altra funzione. Questa dovrebbe essere una soluzione pulita che è più facile da eseguire il debug.
Esempio:
[sum([1.0/j for j in range(i, 100)]) for i in [0, 2, 5, 10]]
Può essere diviso in
[f(i) for i in [0, 2, 5, 10]]
e una funzione
def f(i):
return sum([1.0/j for j in range(i, 100)])
Io uso una funzione che si limita a stampare e restituisce un valore al tempo stesso:
def debug(msg, item):
print('\n' + msg + ':')
pprint(item)
return item
E 'molto utile per il debug di qualsiasi parte di una comprensione lista/dict:
new_lines = [
debug('CUR UPDATED LINE', change(line))
for line
in debug('ALL LINES', get_lines_from_file(filename))
if debug('CUR LINE EMPTY?', not_empty(line))
]
Amo questa risposta! È vergognoso vederlo in fondo, è l'equivalente naturale del debugging della stampa nella programmazione funzionale. –
+1: l'uso divinatorio della list comprehension sono quando il codice in realtà diventa più chiaro e più facile da leggere – nosklo
Questo tipo di sente come resa – Carbon
A volte arrendersi è il modo corretto di agire! Se non riesci a leggerlo, è chiaramente troppo complicato per un one-liner. –