for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
dal terzo ciclo come si esce dal loop corrente e si passa al valore successivo di for row in b:
?python: uscita da due anelli
for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
dal terzo ciclo come si esce dal loop corrente e si passa al valore successivo di for row in b:
?python: uscita da due anelli
Questo si usa un valore booleano per vedere se si è fatto ancora:
done = False
for x in xs:
for y in ys:
if bad:
done = True
break
if done:
break
questo sarà continue
se è stata utilizzata nessuna rottura. Lo else
verrà saltato se ci fosse un'interruzione, quindi vedrà il prossimo break
. Questo approccio ha il vantaggio di non dover usare una variabile, ma potrebbe essere più difficile da leggere per alcuni.
for x in xs:
for y in ys:
if bad:
break
else:
continue
break
Bene, aveva tre anelli, non due. –
Bene, ho pensato che forse OP potrebbe essere in grado di estrapolare a tre cicli. –
@ Teodor: leggi q. attentamente - il ciclo più esterno non ha bisogno di essere chiuso, quindi esempio w/2 loops è la cosa giusta –
testato:
inner_termination=False
for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
<blah>
if break_condition:
inner_termination=True
break
<blah>
if inner_termination:
inner_termination=False
break
for row in b:
more_drugs = True
for drug in drug_input:
for brand in brand_names[drug]:
if something:
more_drugs = False
break
if not more_drugs:
break
Python non ha una struttura di controllo per la rottura da due anelli in una sola volta, quindi è necessario fare manuale di qualcosa di simile.
@cjrh: Sono curioso: perché scriveresti "Grande risposta "ma non votare la risposta? Nessuna pressione ... –
Hai visto la mia risposta? –
Ah, ora capisco! :) –
Se si dispone di tre livelli di looping in un metodo, è probabilmente necessario ripensare il proprio progetto.
all
e any
per evitare di scrivere cicli espliciti.Fare uno di questi dovrebbe significare che non si ha più questo problema.
Non sono sicuro di essere d'accordo, specialmente nel caso di iterazione su una complessa struttura di dati. A volte hai solo dizionari nei dizionari nei dizionari! – katrielalex
@karielalex: Non sei d'accordo con entrambi i punti, o solo con il secondo? –
Con "Se si dispone di tre livelli di looping in un metodo, è probabile che sia necessario ripensare il proprio design." Penso che ci sia una differenza tra il caso di iterare su una struttura dati - nel qual caso l'iterazione multipla è semanticamente una sezione e non dovrebbe essere necessario dividere o sfoltire - e il caso in cui viene fatto troppo in un unico posto . In quest'ultima situazione sono d'accordo con entrambi i punti. Ad esempio, di recente ho creato un DFA che aveva un 'nodo iniziale' '->' arc type' della tabella di transizione -> 'guard' ->' nodo finale'. Per scorrere su tutti i bordi hai bisogno di tre anelli! – katrielalex
for row in b:
ok = True
for drug in drug_input:
if not ok:
break;
for brand in brand_names[drug]:
if not ok:
break
if whatever:
ok = False
try
/except
/raise
, come suggerito nel commento di @ Dgcs, è una possibilità. Un altro è quello di "avvolgere" i due cicli annidati in uno:
for row in b:
for brand in (b for d in drug_input for b in brand_names[d]):
...
ora, un break
dal for brand
ciclo nidificato tornerà al livello di ciclo esterno for row
. Naturalmente, questo funziona solo quando il codice che è qui sostituito da ...
non ha bisogno di vedere il nome drug
associato al farmaco attualmente in esame. E 'questo il tuo caso?
Abbastanza semplice da ottenere nome del farmaco è richiesto. 'per marca, farmaco in ((b, d) per d in drug_input per b in brand_names [d]):' –
riterrei mettere a due cicli interni in funzione e utilizzando ritorno da lì. Probabilmente ripensare a quello che stai facendo e come dare la migliore alternativa a questo però.
Potresti fornire il tuo attuale pseudo-codice, input e output, in modo che potremmo provare a rimuovere la necessità della pausa al primo posto? Abbiamo bisogno di vedere dove le variabili del ciclo sono usate o meglio ancora, qual è l'obiettivo dell'elaborazione.
battiti gestione delle eccezioni impostazione variabili in tutto il luogo IMO
for row in b:
for drug in drug_input:
try:
for brand in brand_names[drug]:
if some_condition:
raise StopIteration
except StopIteration:
break
Le eccezioni sono solo per situazioni eccezionali! –
"Questo è derivato da Exception piuttosto che da StandardError, poiché questo non è considerato un errore nella sua normale applicazione." http://docs.python.org/library/exceptions.html#exceptions.StopIteration – brianz
Ok, è stato un buon ritorno :) Ma seriamente, non gestire le eccezioni per il controllo del flusso. In qualsiasi lingua Un conduttore try-except è uno spunto visivo molto, molto diffuso per "qualcosa di insolito è appena successo". –
Ultime PEP Vedo che richiede questa funzione è 3136 (ed è stata respinta): http://mail.python.org/pipermail/python-3000/2007-July/008663.html
più vicino & cosa più pulito che poteva vedere fino a che dovresti fare quanto segue (e visto che anche i nomi dei tipi sono ambiti, potresti dichiarare LocalBreak all'interno della funzione necessaria):
class LocalBreak(Exception): pass
try:
for i in ...:
for h in ...:
for j in ...:
if should_break(j):
raise LocalBreak()
except LocalBreak:
pass
for a in aa:
for b in bb:
for c in cc:
if c == a[b]:
break
else:
continue
break
Python supporta le istruzioni for...else
. Il blocco else
viene valutato se l'interno break
non viene attivato.
scusa, puoi dirmi per favore cosa aggiunge questo al contenuto attuale? –
Se si dispone di troppi loop incorporati, potrebbe essere il momento per un refactoring. In questo caso, ritengo che il miglior refactor sia quello di spostare i loop in una funzione e utilizzare una dichiarazione return
. Questo forzerà l'uscita da qualsiasi numero di loop. Per esempio:
def example(self, drug_input):
ok = False
for x in drug_input["names"]:
for y in range(drug_input["number_of_drugs"]):
for z in drug_input["list_of_drugs"]:
# do stuff
if ok:
return drug_costs
Ora, forse riformulare la logica come questo è difficile, ma scommetto che il refactoring aiuterà in altri modi.
Probabilmente avrei avvolto questo blocco in una prova e uscirne con un rilancio. –
per favore mostrami come –
Posso chiedere quale condizione nel loop interno forzerebbe un 'break'? –