Reputation: 442
In if/elif/else statements, elif
s are checked if the if
is false, and if both the if
and elif
s are false then the else
is run.
For loops have something similar with the else
keyword - if the loop doesn’t encounter a break, then the code inside else
is run.
So, for loops have an else
equivalent to if/elif/else statements. My question is however, is there an equivalent to elif
.
I’m thinking that it would be something along the lines of:
Run for loop. If no break
is encountered, go onto the next
specified loop
Run the specified for loop, if no break
is encountered, go onto the
next.
Repeat until no more loops are left, and if no break
s have been
encountered up to this point, run the else
.
I’m aware you can emulate this effect. Just as you can do this with if/else statements to emulate the elif
:
if condition:
do_something()
else:
if another_condition:
do_something_else()
else:
default()
you can do this with for loops:
for x in y:
if condition:
break
else:
for n in m:
if another_condition:
break
else:
default()
While the above code is valid, like with if/else statements, it’s faily ugly and I was hoping to find a better alternative.
Upvotes: 0
Views: 218
Reputation: 73460
While the for-loop syntax doesn't allow this (as shown by @Carcigenicate), you can keep nesting levels down by using a try-else
:
try:
for x in y:
if z:
raise SomeException
for m in n:
if o:
raise SomeException
except SomeException:
pass
else:
default()
A cleaner way, however, might wrap the loops in functions:
# these can be more complex non-anonymous functions
f1 = lambda: any(1 for x in y if z)
f2 = lambda: any(1 for m in n if o)
f3 = ...
if not any(f() for f in (f1, f2, f3)):
default()
Upvotes: 1
Reputation: 2058
What if you make the variable that determins whether you should continue global? Since if any of the conditions are met, you don't want to continue with any of the following loops this should work:
def do_something():
for i in range(3):
condition = i < 3
if not condition:
return False
return True
def do_something_else():
for i in range(3):
condition = i < 2
if not condition:
return False
return True
condition_met = True
if condition_met:
print('we start here')
condition_met = do_something()
if condition_met:
print('and should get here')
condition_met = do_something_else()
if condition_met:
print('but not here')
It may not be amazing, but at least it's not nested, and sort of looks like the syntax you're looking for.
You could also use a while loop:
operations = [do_something, do_something_else]
i = 0
while condition_met and i < len(operations):
condition_met = operations[i]()
Upvotes: 1
Reputation: 1
I'm not sure, but maybe while will be ok for you
i = 0
while i < 10:
if condition:
break
i += 1
Upvotes: -3
Reputation: 45740
No. If you look at the grammar of the for
statement:
for_stmt:
| 'for' star_targets 'in' ~ star_expressions ':' [TYPE_COMMENT] block [else_block]
. . .
It ends in an optional else_block
, but nothing else. Your emulation is as good as you'll get I believe.
Upvotes: 6