piccolo ridondanza di codice all'interno while-loop (non si sente pulito)
-
05-10-2019 - |
Domanda
Quindi, in Python (anche se penso che può essere applicato a molte lingue), mi ritrovo con qualcosa di simile abbastanza spesso:
the_input = raw_input("what to print?\n")
while the_input != "quit":
print the_input
the_input = raw_input("what to print?\n")
Forse sono troppo esigente, ma non mi piace come la linea the_input = raw_input("what to print?\n")
deve ottenere ripetuto. Si riduce manutenibilità e l'organizzazione. Ma non vedo alcuna soluzione alternativa per evitare il codice duplicato senza peggiorare ulteriormente il problema. In alcune lingue, potrei scrivere qualcosa di simile:
while ((the_input=raw_input("what to print?\n")) != "quit") {
print the_input
}
Questo è sicuramente non Pythonic, e Python non ha nemmeno consentono di assegnazione all'interno di condizioni di loop per quanto ne so.
Questa correzioni codice valido la ridondanza,
while 1:
the_input = raw_input("what to print?\n")
if the_input == "quit":
break
print the_input
Ma non si sente abbastanza di destra entrambi. Il while 1
implica che questo ciclo verrà eseguito per sempre; Sto utilizzando un ciclo, ma dandogli una condizione di falso e mettere quella reale al suo interno.
Sono troppo schizzinosi? C'è un modo migliore per fare questo? Forse c'è qualche costrutto del linguaggio progettato per questo che io non conosco?
Soluzione
Pensate iteratori - per esempio, nel caso specifico:
for the_input in iter(lambda: raw_input('what to print?\n'), 'quit'):
print the_input
La maggior parte dei loop in Python, tranne che ai livelli molto più bassi di astrazioni, sono meglio implementato come loop for
con l'aiuto di alcuni sottolineando iteratore che cattura il "logica loop" - il iter
incorporato può aiutare (come qui) , a volte genexps (espressioni generatore) può, a volte il modulo standard itertools
biblioteca viene in soccorso.
Il più delle volte si sceglie di codice personalizzato funzioni del generatore (quelli che utilizzano yield
), o più tanto in tanto (quando si ha bisogno davvero sofisticata gestione dello stato) un costume iterator classe ( una definizione del metodo speciale __iter__
come return self
, e next
[[o __next__
nelle ultime versioni di Python]] per tornare "il valore successivo dalla ripetizione).
Catturare la logica loop a parte qualunque cosa sia che si do sulle varie voci in sequenza prodotte dal ciclo in sé è la chiave di astrazione-helper qui!