How to exit an if clause - python

What sorts of methods exist for prematurely exiting an if clause?
There are times when I'm writing code and want to put a break statement inside of an if clause, only to remember that those can only be used for loops.
Lets take the following code as an example:
if some_condition:
...
if condition_a:
# do something
# and then exit the outer if block
...
if condition_b:
# do something
# and then exit the outer if block
# more code here
I can think of one way to do this: assuming the exit cases happen within nested if statements, wrap the remaining code in a big else block. Example:
if some_condition:
...
if condition_a:
# do something
# and then exit the outer if block
else:
...
if condition_b:
# do something
# and then exit the outer if block
else:
# more code here
The problem with this is that more exit locations mean more nesting/indented code.
Alternatively, I could write my code to have the if clauses be as small as possible and not require any exits.
Does anyone know of a good/better way to exit an if clause?
If there are any associated else-if and else clauses, I figure that exiting would skip over them.

(This method works for ifs, multiple nested loops and other constructs that you can't break from easily.)
Wrap the code in its own function. Instead of break, use return.
Example:
def some_function():
if condition_a:
# do something and return early
...
return
...
if condition_b:
# do something else and return early
...
return
...
return
if outer_condition:
...
some_function()
...

from goto import goto, label
if some_condition:
...
if condition_a:
# do something
# and then exit the outer if block
goto .end
...
if condition_b:
# do something
# and then exit the outer if block
goto .end
# more code here
label .end
(Don't actually use this, please.)

while some_condition:
...
if condition_a:
# do something
break
...
if condition_b:
# do something
break
# more code here
break

You can emulate goto's functionality with exceptions:
try:
# blah, blah ...
# raise MyFunkyException as soon as you want out
except MyFunkyException:
pass
Disclaimer: I only mean to bring to your attention the possibility of doing things this way, while in no way do I endorse it as reasonable under normal circumstances. As I mentioned in a comment on the question, structuring code so as to avoid Byzantine conditionals in the first place is preferable by far. :-)

may be this?
if some_condition and condition_a:
# do something
elif some_condition and condition_b:
# do something
# and then exit the outer if block
elif some_condition and not condition_b:
# more code here
else:
#blah
if

For what was actually asked, my approach is to put those ifs inside a one-looped loop
while (True):
if (some_condition):
...
if (condition_a):
# do something
# and then exit the outer if block
break
...
if (condition_b):
# do something
# and then exit the outer if block
break
# more code here
# make sure it is looped once
break
Test it:
conditions = [True,False]
some_condition = True
for condition_a in conditions:
for condition_b in conditions:
print("\n")
print("with condition_a", condition_a)
print("with condition_b", condition_b)
while (True):
if (some_condition):
print("checkpoint 1")
if (condition_a):
# do something
# and then exit the outer if block
print("checkpoint 2")
break
print ("checkpoint 3")
if (condition_b):
# do something
# and then exit the outer if block
print("checkpoint 4")
break
print ("checkpoint 5")
# more code here
# make sure it is looped once
break

Generally speaking, don't. If you are nesting "ifs" and breaking from them, you are doing it wrong.
However, if you must:
if condition_a:
def condition_a_fun():
do_stuff()
if we_wanna_escape:
return
condition_a_fun()
if condition_b:
def condition_b_fun():
do_more_stuff()
if we_wanna_get_out_again:
return
condition_b_fun()
Note, the functions don't HAVE to be declared in the if statement, they can be declared in advance ;) This would be a better choice, since it will avoid needing to refactor out an ugly if/then later on.

There is another way which doesn't rely on defining functions (because sometimes that's less readable for small code snippets), doesn't use an extra outer while loop (which might need special appreciation in the comments to even be understandable on first sight), doesn't use goto (...) and most importantly let's you keep your indentation level for the outer if so you don't have to start nesting stuff.
if some_condition:
...
if condition_a:
# do something
exit_if=True # and then exit the outer if block
if some condition and not exit_if: # if and only if exit_if wasn't set we want to execute the following code
# keep doing something
if condition_b:
# do something
exit_if=True # and then exit the outer if block
if some condition and not exit_if:
# keep doing something
Yes, that also needs a second look for readability, however, if the snippets of code are small this doesn't require to track any while loops that will never repeat and after understanding what the intermediate ifs are for, it's easily readable, all in one place and with the same indentation.
And it should be pretty efficient.

Here's another way to handle this. It uses a single item for loop that enables you to just use continue. It prevents the unnecessary need to have extra functions for no reason. And additionally eliminates potential infinite while loops.
if something:
for _ in [0]:
# Get x
if not x:
continue
# Get y
if not y:
continue
# Get z
if not z:
continue
# Stuff that depends on x, y, and z

Effectively what you're describing are goto statements, which are generally panned pretty heavily. Your second example is far easier to understand.
However, cleaner still would be:
if some_condition:
...
if condition_a:
your_function1()
else:
your_function2()
...
def your_function2():
if condition_b:
# do something
# and then exit the outer if block
else:
# more code here

So here i understand you're trying to break out of the outer if code block
if some_condition:
...
if condition_a:
# do something
# and then exit the outer if block
...
if condition_b:
# do something
# and then exit the outer if block
# more code here
One way out of this is that you can test for for a false condition in the outer if block, which will then implicitly exit out of the code block, you then use an else block to nest the other ifs to do something
if test_for_false:
# Exit the code(which is the outer if code)
else:
if condition_a:
# Do something
if condition_b:
# Do something

The only thing that would apply this without additional methods is elif as the following example
a = ['yearly', 'monthly', 'quartly', 'semiannual', 'monthly', 'quartly', 'semiannual', 'yearly']
# start the condition
if 'monthly' in b:
print('monthly')
elif 'quartly' in b:
print('quartly')
elif 'semiannual' in b:
print('semiannual')
elif 'yearly' in b:
print('yearly')
else:
print('final')

There are several ways to do it. It depends on how the code is implemented.
If you exit from a function, then use return; no code will be executed after the return keyword line. Then the example code is:
def func1(a):
if a > 100:
# some code, what you want to do
return a*a
if a < 100:
# some code, what you want to do
return a-50
if a == 100:
# some code, what you want to do
return a+a
If you exit from a loop, use break. No code will be executed after break keyword. Then the example code is, for while and for loops:
a = 1
while (True):
if (a == 10):
# some code, what you want to do
break
else:
a=a+1
print("I am number", a)
for i in range(5):
if i == 3:
break
print(i)
If you exit from the basic conditional, then you can use the exit() command directly. Then code after the exit() command will not be executed.
NB: This type of code is not preferable. You can use a function instead of this. But I just share the code for example.
The example code is:
if '3K' in FILE_NAME:
print("This is MODIS 3KM file")
SDS_NAME = "Optical_Depth_Land_And_Ocean"
elif 'L2' in FILE_NAME:
print("This is MODIS 10KM file")
SDS_NAME = "AOD_550_Dark_Target_Deep_Blue_Combined"
exit()
else:
print("It is not valid MODIS file")

I scrolled through, and nobody mentioned this technique. It's straightforward compared to other solutions and if you do not want to use a try-except statement, this may be your best option.
#!/usr/bin/python3
import sys
foo = 56
if (foo != 67):
print("ERROR: Invalid value for foo")
sys.exit(1)

use return in the if condition will returns you out from the function,
so that you can use return to break the the if condition.

Related

Function with two loops

I want to make a function what must have 2 loops:
must check that at least 2 characters (letters) are inserted
if the two characters are in the form that the variable must receive at the end, the variable receives the correct orthographic form.
Here is my code (but it throws me in infinite loop) [Please be indulgent im a begginer (: ] :
def sede():
while True:
import re
var_sede_0 = input("Sede : ")
if re.match("([a-zA-Z]+.*?){2,}", var_sede_0):
while True:
if var_sede_0.lower() in 'torino (to)':
var_sede_0 = 'Torino (TO)'
break
elif var_sede_0.lower() in 'reggio calabria (rc)':
var_sede_0 = 'Reggio Calabria (RC)'
break
else:
print("sbagliato")
continue
break
else:
print("formato sbagliato")
continue
return var_sede_0
var_sede = sede()
Your inner loop is the problem:
while True:
if var_sede_0.lower() in 'torino (to)':
var_sede_0 = 'Torino (TO)'
break
elif var_sede_0.lower() in 'reggio calabria (rc)':
var_sede_0 = 'Reggio Calabria (RC)'
break
else:
print("sbagliato")
continue
Consider that nowhere in this loop do you take in new input, so var_sede_0 can never possibly change. Given that, if the first two predicates (if statements) evaluate to false, then you will be in an infinite loop printing out sbagliato. You can probably simply remove the while True (the inner one) and get to what you want.
It is key to note that break and continue really only affect the immediate while context that they are in - they will not 'speak to' the outer while loop.
You also probably do not want to be importing re on every loop. Move import re to the top of your file.

python loop only works after putting code in a function

In a Python 3 script, I have a part where I have a for loop, where I want to do stuff and then do a validation check. If it does NOT pass the validation check, I want to skip processing the rest of the loop and just move on to the next item in the loop. If it passes the validation check, I want the script to do some more stuff and then perform another validation check where it does the same as the first validation check; if it does not pass validation, skip the rest of the code in the for loop and move on to the next iteration of the loop; if it passes validation, keep processing code in the loop. I might do this 3-5 times within the loop. But here's the thing...
When I set up my script like this, it does NOT work as intended:
for example in examples:
##### do some stuff here
##### then have a VALIDATION CHECK here
if "dates" in paydata:
continue
##### then do do some more stuff here
##### then have another VALIDATION CHECK here
if 'Payment' in pay_plan:
continue
##### then do do some more stuff here
##### then have another VALIDATION CHECK here
if 'Plan' in pay_plan:
continue
##### continue on with the script and do some stuff here, etc.
But, when I basically put my if statements into functions and then my code looks like the following (with my if statements based on the return of the function), it works as intended. My question, then, is why do the continue statements do one thing (NOT work as intended) in the first code example but DO work in the second code example (work as intended). What am I missing in this "head-scratcher"?
##### create validation-check functions
def func_1(id, paydata):
if "dates" in paydata:
return(True)
else:
return(False)
def func_2(id, pay_plan):
if 'Payment' in pay_plan:
return(True)
else:
return(False)
def func_3(id, plan):
if 'Plan' in plan:
return(True)
else:
return(False)
for example in examples:
#####
##### do some stuff here
#####
##### then have a VALIDATION CHECK here
md_check = multiple_dates(id, paydata)
if md_check == True:
continue
#####
##### then do do some more stuff here
#####
##### then have another VALIDATION CHECK here
on_pp = on_payment_plan(id, pay_plan)
if on_pp == True:
continue
#####
##### then do do some more stuff here
#####
##### then have another VALIDATION CHECK here
on_pp = on_payment_plan(id, plan)
if on_pp == True:
continue
#####
##### continue on with the script and do some stuff here
#####
continue does not do what you think it does. The keyword continue sends the loop back to the beginning. It's not to be used to allow a loop to continue as the name implies it's for when a condition has been met but you need the loop to continue going.
To make your loop keep going a better check would be in the format:
if not md_check:
break
This inverses your logic and exits the loop if your condition is not present. The same is applicable here:
if on_pp == True:
continue
Should be:
if not on_pp:
break
A small working example to show how continue works:
>>> x = 1
>>> while x < 50:
if not x & 1:
print('{} is even'.format(x))
x += 1
else:
print('{} is odd'.format(x))
x += 1
continue
print('this only prints if x is even')
1 is odd
2 is even
this only prints if x is even
3 is odd
4 is even
this only prints if x is even
5 is odd
6 is even
this only prints if x is even
7 is odd
8 is even
this only prints if x is even
9 is odd
10 is even
# snipped for brevity

python break a function nested inside a loop

I have the following piece of code:
for x in Listofurls:
function(urlquery)
function(htmlmining)
how the statement in function should be written
so that i can continue the loop moving to the next item
when the query does not match my research like
def(urlquery):
url=urlquery
Urlopen = urllib.request.urlopen(url)
Url_read = parse(Urlopen)
if 'text' not in Url_read.read():
#here is where i want a statement to stop and go to the next
#item in the loop like 'continue' in a for loop
You can use StopIteration to exit from all loops until it's caught;
try:
for i in range(10):
if i == 5:
raise StopIteration
else:
print i
except StopIteration:
print "Caught"
gives:
0
1
2
3
4
Caught
The StopIteration Exception is exactly that, an exception, not an error;
Raised by an iterator‘s next() method to signal that there are no
further values. This is derived from Exception rather than
StandardError, since this is not considered an error in its normal
application.
You can put it as deeply as you want in your nested loops, but you have to catch it at the level you want to break out of (i.e. the level at which you want to stop iteration) to.
Looking at your question, and trying to make sense of what you've written, it looks like you want to do something like this (maybe?)
for url in listOfURLs:
if urlquery(url):
htmlmining(url)
def urlquery(url):
page = parse(urllib.request.urlopen(url))
return 'text' in page.read():
#here is where i want a statement to stop and go to the next
#item in the loop like 'continue' in a for loop
This will then only run htmlmining(url) when 'text' is in the page you're parsing. If it's not, it will skip that entry and move onto the next one.
Have the inner function return True if you want to continue:
def urlquery(url):
urlopen = urllib.request.urlopen(url)
url_read = parse(urlopen)
if 'text' not in url_read.read():
# here is where I want a statement to stop and go to the next
return True
Then, the outer function can be:
for x in list_of_urls:
if urlquery(x):
continue
htmlmining(x)
Note that the code you posted was not valid Python. The above is my best guess as to what you meant.
Also, please read the Python style guide.
i finally found a solution to the question:
def urlquery(url):
urlopen = urllib.request.urlopen(url)
url_read = parse(urlopen)
if 'text' not in url_read.read():
return
else:
myurl='text' in url_read.read()
return myurl
and the for loop as follows:
for x in Listofurls:
TextAvailable=function(urlquery)
if not TextAvailable:
continue
function(htmlmining)
i am not sure this is the cleanest way to proceed but it works.

Python: While Loop Check Throughout Loop if True

I have a very simple problem: I have made a while loop, and in the middle of it, set the initial condition to false. This, however, does not stop the loop and runs entirely through, (somewhat obviously,) until it attempts to unsuccessfully go through again. Here is a simplified construction of what I have.
while(a):
print("hi")
a = False
print("bye")
This returns:
hi
bye
Again I would like to only return hi; I want the loop to continually check if its satisfied.
Any help greatly appreciated.
Use:
return, or break
while a:
print('hi')
a = False
if not a:
break
print('bye')
In a function or loop, when something is returned, the function or loop terminates. You could also return True, or break which is a specific way to 'break' out of a loop.
Since the condition is true to start with (by design), the body of the loop will execute at least once. The fact you do something in the body of the loop to make the loop condition false doesn't stop the current iteration. It just means there won't be a next iteration after this one is done.
So if you want to get out in the middle of the current iteration, then you need to use break, return, or something more sophisticated like #inspectorG4dget's suggestion.
while(a):
print("hi")
a = False
if a:
print("bye")
OR
while(a):
for s in ["hi", "bye"]:
if a:
print(s)
if someCondition:
a = False

Is the `else:` correct/necessary in this Python program?

Is the line of else: correct/necessary in this Python program?
from random import randrange
for n in range(10):
r = randrange(0,10) # get random int in [0,10)
if n==r: continue # skip iteration if n=r
if n>r: break # exit the loop if n>r
print n
else:
print "wow, you are lucky!\n"
if n<9:
print "better luck next time\n
From the documentation:
Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement
So yes, it's correct in your example. Although I've never been a fan of it, using an else clause on a loop makes code confusing at first, I'd rather use a boolean flag for achieving the same effect. IMHO else should be used only for conditionals.
from random import randrange
for n in range(10):
r = randrange(0,10)
if n=r: continue # there should be ==
if n>r: break
print n # should be "\n" ?
else:
print "wow, you are lucky!\n" # Yes, you are! Your python interpreter can make miracles :). Try to run me.append(SexyChick(10)) and let's see what happens!
for...else construct is actually valid. else branch is executed if the loop has not been terminated by break. Look here.

Categories