I expect thatās much harder. Detemining whether for/else
or while/else
are ācorrectā can require deep knowledge of intended semantics. For example, hereās a primalty tester Iāve been using for a very long time:
Code
import math
from random import randrange
def pp(n, k=20, *, gcd=math.gcd, pri=3*5*7*11*13*17*19):
"""
Return True iff n is a probable prime, using k Miller-Rabin tests.
When False, n is definitely composite.
"""
if n < 4:
return 2 <= n <= 3
d = nm1 = n-1
s = 0
while d & 1 == 0:
s += 1
d >>= 1
if s == 0:
return False # n >= 4 and even
if n >= pri and gcd(n, pri) > 1:
return False
ss = range(1, s)
for _ in range(k):
a = randrange(2, nm1)
x = pow(a, d, n)
if x == 1 or x == nm1:
continue
for _ in ss:
x = x*x % n
if x == nm1:
break
if x == 1:
return False
else:
return False
return True
Is the for/else
there correct? Yes. But most readers will have to take my word for it .
One thing that could be done is to trigger a compile-time error if the loop body doesnāt contain a break
at all (then the else:
clause is unreachable). Iāve seen newbies trip over that more than once on Stackoverflow.
More common, but very much harder to detect:
for ...: # or while
if condition found:
# do _everything_ needed if it's found ...
break
else:
# do everything needed if it's not found
Thr focus of the search loop is on searching. So parts of the ā# do everything needed if itās found ā¦ā part tend to end up, by mistake, after the loop construct is over. So ābetterā syntax may have been a āloop/ifbreak/elseā structure:
for ...: # or while
if condition found:
break
if break:
# do everything_needed if it's found ...
else:
# do everything needed if it's not found
Then the search loop body is solely devoted to searching, and the āfoundā and ānot foundā suites would be at the same indentation level too.
In any case, while I donāt use for/else
often, itās a very good fit when it is used, I would sorely miss it, and Iād be astonished if any of my uses didnāt work as intended. Itās not hard, just a bit of a learning curve due to novelty.