RFC: For Loop Invariants
Elliott Dehnbostel
pydehnbostel at gmail.com
Fri Apr 10 16:44:05 EDT 2020
Hello Everyone,
I've also posted this to the python-ideas mailing list, but I thought to
post here as well for a more general audience.
If I've done this incorrectly, please let me know so that I can
improve/revise. I'm new to the Python community and quite enjoy the more
functional features of Python 3, but have I have a peeve about it. I'd like
to propose and discuss the following enhancement to Python 3:
*Consider the following trivial for-loop:*
chars = "abcaaabkjzhbjacvb"
seek = {'a','b','c'}
count = 0for a in chars:
if a in seek:
count += 1
Gross. Twice nested for a simple count.
*We could refactor the block like so:*
chars = "abcaaabkjzhbjacvb"
seek = {'a','b','c'}
count = 0for a in filter(lambda c: c in seek, chars): count += 1
Which is all well and good, but doesn't quite read like English. It's
verbose, too.
It also uses advanced concepts new programmers may not understand.
*We could do this:*
chars = "abcaaabkjzhbjacvb"
seek = {'a','b','c'}
count = sum([1 for a in chars if a in seek])
However, this changes important semantics by creating an entire new
list before summing.
Also, adding just one more expression to the most nested block thwarts
that refactor.
I propose the following enhancement:
chars = "abcaaabkjzhbjacvb"
seek = {'a','b','c'}
count = 0for a in chars if a in seek: count += 1
*What happened there?*
I've allowed a condition to follow the "for" construct without a colon
or newline between.
*To be clear, this remains incorrect:*
chars = "abcaaabkjzhbjacvb"
seek = {'a','b','c'}
count = 0for a in chars # No colon prior to the newline
if a in seek:
count += 1
*In summary:*
for a in iterable if cond:
# code block
*Becomes syntactic sugar for:*
for a in iterable:
if cond:
# code block
*Value proposal:*
I assert that the inlined 'if' condition pattern is superior to the
alternative refactors.
Right now, the way to acquire an invariant without nesting the block would be:
for a in iterable:
if not cond:
continue
But this is messy and not particularly Pythonic.
The filter approach uses concepts that should not be necessary for this task.
The comprehension approach has different, undesirable semantics.
*Conclusion:*
I wanted to submit my thoughts here before getting too deep into this.
Any input would be appreciated!
Thanks everyone.
More information about the Python-list
mailing list