Opposite of Python for ... else - python

The following Python code will result in n (14) being printed, as the for loop is completed.
for n in range(15):
if n == 100:
break
else:
print(n)
However, I want the opposite of this. Is there a way to do a for ... else (or while ... else) loop, but only execute the else code if the loop did break?

There is no explicit for...elseifbreak-like construct in Python (or in any language that I know of) because you can simply do this:
for n in range(15):
if n == 100:
print(n)
break
If you have multiple breaks, put print(n) in a function so you Don't Repeat Yourself.

A bit more generic solution using exceptions in case you break in multiple points in the loop and don't want to duplicate code:
try:
for n in range(15):
if n == 10:
n = 1200
raise StopIteration()
if n > 4:
n = 1400
raise StopIteration()
except StopIteration:
print n

I didn't really like the answers posted so far, as they all require the body of the loop to be changed, which might be annoying/risky if the body is really complicated, so here is a way to do it using a flag. Replace _break with found or something else meaningful for your use case.
_break = True
for n in range(15):
if n == 100:
break
else:
_break = False
if _break:
print(n)
Another possibility, if it is a function that does nothing if the loop doesn't find a match, is to return in the else: block:
for n in range(15):
if n == 100:
break
else:
return
print(n)

Use:
for n in range(15):
if n == 100:
break
else:
print("loop successful")
if n != range(15)[-1]:
print("loop failed")

Related

Why my for loop is not iterating all the values

When I run this code and give input as 25 it should return me its not a prime num,
But when I debug the code the range values are not iterating into if condition, only the first value of the range is passed and if its not == 0 it moves to the else part.
def find(x):
if x > 1:
for i in range(2,x):
if x % i == 0:
return "its not a prime num"
else:
return "Its a prime num"
user = int(input("Enter your no: "))
print(find(user))
Please help me why its working like this , I am new to programming . TIA
As stated in a comment, this is an easy fix. Simply move the else statement's return to outside of the loop.
def find(x):
if x > 1:
for i in range(2,x):
if x % i == 0:
return "its not a prime num"
return "Its a prime num"
user = int(input("Enter your no: "))
print(find(user))
Using a return inside of a loop will break it and exit the function even if the iteration is still not finished. use print instead.
I discovered that for whatever reason for loops never run with the final value an easy fix is to just add 1 to the ending value.

Need help properly executing a "break" statement in python

I have some code which gives me the answer I want, but I'm having trouble stopping it once I get the
answer I want.
Here's my code:
multiples = range(1,10)
n = 1
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
This is an attempt at solving problem 5 of Project Euler. Essentially, I'm supposed to get the smallest multiple of all the digits within a given range.
Now, when i run the above code using the example given (1-10 should yield 2520 as the smallest multiple), i get the answer right. However, the code continues to run infinitely and print the answer without breaking. Also, the moment I add the break statement to the end like so:
multiples = range(1,10)
n = 1
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
break
The code just keeps spamming the number 30. Any ideas why this is happening. For the record, I'm not really looking for an alternative solution to this question (the goal is to learn after all), but those are welcome. What I want to know most of all is where I went wrong.
You never break out of your while loop. The for is the entire while body. break interrupts only the innermost loop; you have no mechanism to leave the while loop. Note that your continue doesn't do anything; it applies to the for loop, which is about to continue, anyway, since that's the last statement in the loop (in that control flow).
I can't really suggest a repair for this, since it's not clear how you expect this to solve the stated problem. In general, though, I think that you're a little confused: you use one loop to control n and the other to step through divisors, but you haven't properly tracked your algorithm to your code.
One way to deal with this is to have an exception. At best a custom one.
multiples = range(1,10)
n = 1
class MyBreak(Exception):
pass
while n>0:
try:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
raise MyBreak()
except MyBreak:
# now you are free :)
break
With this brake you stop only for loop, to exit whole cycle you should create trigger variable, for example:
multiples = range(1,10)
n = 1
tg = 0
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
tg = 1
break
if tg != 0:
break
Or it'll be better to use a function and stop a cycle by return:
def func():
multiples = range(1,10)
n = 1
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
return n

Finding fault in this recursive list addition in python

I need to create a program that takes in an array of numbers, check if each number is greater than the sum of all previous numbers, and output true if the condition is met, and false, if not. My trial is presented below:
import fileinput
a0 = [int(i) for i in fileinput.input()]
a = a0[1:]
b=[]
for i in range(1, a0[0]+1):
b.append(a[i])
if (a[i+1] > sum(b)):
print("true")
break
else:
print ("false")
break
My program works for half of the test cases but fails for the other test. Could you please help me figure out what i am doing wrongly. Many thanks for your assistance.
You are breaking too early in the true case. Only because the first element checks, doesn't mean all others will, too:
for i in range(1, a0[0]+1):
b.append(a[i])
if (a[i+1] <= sum(b)):
print ("false")
break
else: # for-else: else is executed only if loop isn't `break`ed out of
print("true")
Only once the loop has finished without finding a counter example, you can be sure that it holds for the entire list.
A more concise of writing this, would be:
import fileinput
_, *a = (int(i) for i in fileinput.input())
s = 0 # just keep track of total
for num in a:
if (num <= s):
print("false")
break
s += num
else:
print("true")

Break outside of two loops

I'm writing a code with a while loop inside a while loop and am wondering how to break out of the outer loop if I meet the necessary conditions in the inner loop.
while N <= 8:
while i < 60:
if this:
that
elif this:
that other thing
else:
break
i += 1
if while loop has found the right thing:
N += 1
else:
change conditions
This break command will only break out of the first loop, so I'm wondering how to simply break out both. It might be worth mentioning that all this is in another for loop which I wouldn't want to break out of. Thank you.
Encapsulate it in a function and return when you are done?
Use a flag; trigger is used here
trigger = False
while N <= 8:
while i < 60:
if this:
that
elif this:
that other thing
else:
trigger = True
break
i += 1
if trigger:
break
elif while loop has found the right thing:
N += 1
else:
change conditions
Use flag:
flag = True
while N <= 8:
while i < 60:
if this:
that
elif this:
that other thing
else:
flag = False # To exit from outer while loop
break
i += 1
if(not flag):
break # Condition in inner loop is met
if while loop has found the right thing:
N += 1
else:
change conditions

Python indentation, allignment of IFs and ELSEs

I am new to python and i am still strugling to understand how the sytnax works, how you need to allign your If and else to make it work correctly. How do i really know which else goes with which if? especially when using nested code blocks.
In the code below for the else followed by the comment Prime! from what i understand that else goes with the statement if (n % div == 0): but then why is it alligned with the FOR statement instead?
the last else statement i think goes with if n == 2: but the else is not alligned with it, instead it is after. For the same statement if n == 2: why is n += 1 alligned before pime_count +=1 and not after it.
I understand that the placement of the Else and if is very important because if i decided to move any of them the code stops working. What i can't seem to understand is how does python know which else goes with which if, if the allignment doesnt seem to be consistent.
#!/usr/bin/env python
#
# Problem Set 1a
#
# A program that computes and prints the 1000th prime number.
# Finds primes using trial division (least efficient method)
#------------------------------------------------------------
prime_count = 0
n = 2
while (prime_count <= 1000):
#if even, check for 2, the only even prime
if (n % 2 == 0):
if n == 2:
prime_count += 1
n += 1
else:
# number is odd, possible prime
for div in range(3, n, 2):
if (n % div == 0):
# not a prime
n += 1
break
else:
# prime!
prime_count += 1
if prime_count == 1000:
print "The 1000 prime is", n
else:
n += 1
The rule is very simple: the else clause must have the same indentation as the statement it refers to (most commonly, an if statement).
Now, here:
for div in range(3, n, 2):
if (n % div == 0):
# not a prime
n += 1
break
else:
...
you are not using if-else, you are using for-else!
This construct means "execute the else block unless the loop has terminated through a break".
See for ... else in Python for a discussion.
An if goes with an else at the same indentation, so long as there are no other things at lower indentation between them. They have to be in the same "block". However, in your case, the else that's followed by # prime! is not actually joined to an if at all, but rather to the for div in range(3, n, 2): loop before it!
An else attached to a for loop means "execute this code if the for loop completed without hitting a break statement". It can be useful sometimes, but it is often confusing for people who haven't encountered it before!
I think this can help you to understand how python indentation works http://psung.blogspot.com/2007/12/for-else-in-python.html
In a construct like this one:
for i in foo:
if bar(i):
break
else:
baz()
the else suite is executed after the for, but only if the for terminates normally (not by a break).
In other situations else goes after if
There are 2 rules which are fairly simple,
The indent of the if and else have to be the same
for x in range(15):
if x > 10:
print 'x is more than 10'
else:
print 'x is less than or equal to 10'
Nothing with an indent lower than or equal to that of if and elseshould come in between them
So, this is invalid/ will raise a SyntaxError.
for x in range(15):
if x > 10:
print 'x is more than 10'
print x
else:
print 'x is less than or equal to 10'
Also, As stated in PEP 8
Use 4 spaces per indentation level.
for div in range(3, n, 2):
if (n % div == 0):
# not a prime
n += 1
break
else: # at same indent as for
# prime!
Also, your indent above means for...else loop is made (here else clause is executed if the for loop is exited using break), not if..else.

Categories

Resources