On 03/03/2017 04:36 AM, Nick Coghlan wrote:
On 2 March 2017 at 21:06, Wolfgang Maier
<wolfgang.ma...@biologie.uni-freiburg.de
<mailto:wolfgang.ma...@biologie.uni-freiburg.de>> wrote:
- overall I looked at 114 code blocks that contain one or more breaks
Thanks for doing that research :)
Of the remaining 19 non-trivial cases
- 9 are variations of your classical search idiom above, i.e.,
there's an else clause there and nothing more is needed
- 6 are variations of your "nested side-effects" form presented
above with debatable (see above) benefit from except break
- 2 do not use an else clause currently, but have multiple breaks
that do partly redundant things that could be combined in a single
except break clause
Those 8 cases could also be reviewed to see whether a flag variable
might be clearer than relying on nested side effects or code repetition.
[...]
This is a case where a flag variable may be easier to read than loop
state manipulations:
may_have_common_prefix = True
while may_have_common_prefix:
prefix = None
for item in items:
if not item:
may_have_common_prefix = False
break
if prefix is None:
prefix = item[0]
elif item[0] != prefix:
may_have_common_prefix = False
break
else:
# all subitems start with a common "prefix".
# move it out of the branch
for item in items:
del item[0]
subpatternappend(prefix)
Although the whole thing could likely be cleaned up even more via
itertools.zip_longest:
for first_uncommon_idx, aligned_entries in
enumerate(itertools.zip_longest(*items)):
if not all_true_and_same(aligned_entries):
break
else:
# Everything was common, so clear all entries
first_uncommon_idx = None
for item in items:
del item[:first_uncommon_idx]
(Batching the deletes like that may even be slightly faster than
deleting common entries one at a time)
Given the following helper function:
def all_true_and_same(entries):
itr = iter(entries)
try:
first_entry = next(itr)
except StopIteration:
return False
if not first_entry:
return False
for entry in itr:
if not entry or entry != first_entry:
return False
return True
- finally, 1 is a complicated break dance to achieve sth that
clearly would have been easier with except break; from typing.py:
[...]
I think is another case that is asking for the inner loop to be factored
out to a named function, not for reasons of re-use, but for reasons of
making the code more readable and self-documenting :)
It's true that using a flag or factoring out redundant code is always a
possibility. Having the except clause would clearly not let people do
anything they couldn't have done before.
On the other hand, the same is true for the else clause - it's only
advantage here is that it's existing already - because a single flag
could always distinguish between a break having occurred or not:
brk = False
for item in iterable:
if some_condition:
brk = True
break
if brk:
do_stuff_upon_breaking_out()
else:
do_alternative_stuff()
is a general pattern that would always work without except *and* else.
However, the fact that else exists generates a regrettable asymmetry in
that there is direct language support for detecting one outcome, but not
the other.
Stressing the analogy to try/except/else one more time, it's as if
"else" wasn't available for try blocks. You could always use a flag to
substitute for it:
dealt_with_exception = False
try:
do_stuff()
except:
deal_with_exception()
dealt_with_exception = True
if dealt_with_exception:
do_stuff_you_would_do_in_an_else_block()
So IMO the real difference here is that the except clause after for
would require adding it to the language, while the else clauses are
there already. With that we're back at the high bar for adding new syntax :(
A somewhat similar case that comes to mind here is PEP 315 -- Enhanced
While Loop, which got rejected for two reasons, the first one being
pretty much the same as the argument here, i.e., that instead of the
proposed do .. while it's always possible to factor out or duplicate a
line of code. However, the second reason was that it required the new
"do" keyword, something not necessary for the current suggestion.
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/