Re: clever exit of nested loops

2018-09-27 Thread Gregory Ewing

Neal Becker wrote:
but it does violate the principle "Exceptions should 
be used for exceptional conditions).


Python doesn't really go in for that philosophy.
Exceptions are often used for flow control, e.g.
StopIteration.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: clever exit of nested loops

2018-09-27 Thread Thomas Jollans
On 2018-09-26 21:06, Mark Lawrence wrote:
> 
> To me the Ned Batchelder presentation
> https://www.youtube.com/watch?v=EnSu9hHGq5o "Loop like a Native" is the
> definitive way on how to deal with loops in Python.
> 
Hear, hear.

Great talk.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: clever exit of nested loops

2018-09-27 Thread Neal Becker
Christian Gollwitzer wrote:

> Am 26.09.18 um 12:28 schrieb Bart:
>> On 26/09/2018 10:10, Peter Otten wrote:
>>> class Break(Exception):
>>> pass
>>>
>>> try:
>>> for i in range(10):
>>> print(f'i: {i}')
>>> for j in range(10):
>>> print(f'\tj: {j}')
>>> for k in range(10):
>>> print(f'\t\tk: {k}')
>>>
>>> if condition(i, j, k):
>>> raise Break
>>> except Break:
>>> pass
>>>
>> 
>> For all such 'solutions', the words 'sledgehammer' and 'nut' spring to
>> mind.
>> 
>> Remember the requirement is very simple, to 'break out of a nested loop'
>> (and usually this will be to break out of the outermost loop). What
>> you're looking is a statement which is a minor variation on 'break'.
> 
> Which is exactly what it does. "raise Break" is a minor variation on
> "break".
> 
>> Not
>> to have to exercise your imagination in devising the most convoluted
>> code possible.
> 
> To the contrary, I do think this solution looks not "convoluted" but
> rather clear. Also, in Python some other "exceptions" are used for a
> similar purpose - for example "StopIteration" to signal that an iterator
> is exhausted. One might consider to call these "signals" instead of
> "exceptions", because there is nothing exceptional, apart from the
> control flow.
> 
> Christian
> 
> 

I've done the same before myself (exit from nested blocks to a containing 
block using exception), but it does violate the principle "Exceptions should 
be used for exceptional conditions).

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: clever exit of nested loops

2018-09-27 Thread Christian Gollwitzer

Am 26.09.18 um 12:28 schrieb Bart:

On 26/09/2018 10:10, Peter Otten wrote:

 class Break(Exception):
 pass

 try:
 for i in range(10):
 print(f'i: {i}')
 for j in range(10):
 print(f'\tj: {j}')
 for k in range(10):
 print(f'\t\tk: {k}')

 if condition(i, j, k):
 raise Break
 except Break:
 pass



For all such 'solutions', the words 'sledgehammer' and 'nut' spring to 
mind.


Remember the requirement is very simple, to 'break out of a nested loop' 
(and usually this will be to break out of the outermost loop). What 
you're looking is a statement which is a minor variation on 'break'. 


Which is exactly what it does. "raise Break" is a minor variation on 
"break".


Not 
to have to exercise your imagination in devising the most convoluted 
code possible.


To the contrary, I do think this solution looks not "convoluted" but 
rather clear. Also, in Python some other "exceptions" are used for a 
similar purpose - for example "StopIteration" to signal that an iterator 
is exhausted. One might consider to call these "signals" instead of 
"exceptions", because there is nothing exceptional, apart from the 
control flow.


Christian


--
https://mail.python.org/mailman/listinfo/python-list


Re: clever exit of nested loops

2018-09-27 Thread John Ladasky
On Wednesday, September 26, 2018 at 12:50:20 AM UTC-7, vito.d...@gmail.com 
wrote:

> I have "abused" the "else" clause of the loops to makes a break "broke" more 
> loops

I did this once upon a time.  In recent years, when I start writing tricky 
nested loops, I frequently find myself reaching for itertools.product() to 
flatten the loops instead.

This code accomplishes the same task as yours.  I'll leave it to you to decide 
whether you prefer it.  There are things that I dislike about it, but the flow 
control part is clear.


from itertools import product

msgs = ("i: {}", "\tj: {}", "\t\tk: {}")
old = 3*[None]
for new in product(range(10), repeat=3):
for n, (msg, changed) in enumerate(zip(msgs, [x!=y for x, y in zip(old, 
new)])):
if changed:
print(msg.format(new[n]))
if condition(*new):# your condition() took three separate arguments
break
old = new

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: clever exit of nested loops

2018-09-26 Thread Mark Lawrence

On 26/09/18 08:50, vito.detul...@gmail.com wrote:

Hi
Today I've added a couple of lines in my source code, and I'm very ashamed of 
it.
it "runs", and I know what it does (for now), but it's "too clever".
I have "abused" the "else" clause of the loops to makes a break "broke" more 
loops


 for i in range(10):
 print(f'i: {i}')
 for j in range(10):
 print(f'\tj: {j}')
 for k in range(10):
 print(f'\t\tk: {k}')

 if condition(i, j, k):
 break

 else:# if there weren't breaks in the inner loop,
 continue # then make anoter outer loop,
 break# else break also the outer one

 else:
 continue
 break

the "magic" is in that repeated block... it's so convoluted to read... still it's very 
useful to omit "signals" variables or the need to refactor it in a function with an 
explicit return or other solutions.

is there any chance to extends the python grammar to allow something like


 for i in range(10) and not break:
 print(f'i: {i}')
 for j in range(10) and not break:
 print(f'\tj: {j}')
 for k in range(10):
 print(f'\t\tk: {k}')

 if condition(i, j, k):
 break


with the semantics of break a loop if an inner loop "broke"?

  



To me the Ned Batchelder presentation 
https://www.youtube.com/watch?v=EnSu9hHGq5o "Loop like a Native" is the 
definitive way on how to deal with loops in Python.


--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: clever exit of nested loops

2018-09-26 Thread Peter Otten
vito.detul...@gmail.com wrote:

> Hi
> Today I've added a couple of lines in my source code, and I'm very ashamed
> of it. it "runs", and I know what it does (for now), but it's "too
> clever". I have "abused" the "else" clause of the loops to makes a break
> "broke" more loops
> 
> 
> for i in range(10):
> print(f'i: {i}')
> for j in range(10):
> print(f'\tj: {j}')
> for k in range(10):
> print(f'\t\tk: {k}')
> 
> if condition(i, j, k):
> break
> 
> else:# if there weren't breaks in the inner loop,
> continue # then make anoter outer loop,
> break# else break also the outer one
> 
> else:
> continue
> break
> 
> the "magic" is in that repeated block... it's so convoluted to read...
> still it's very useful to omit "signals" variables or the need to refactor
> it in a function with an explicit return or other solutions.
> 
> is there any chance to extends the python grammar to allow something like
> 
> 
> for i in range(10) and not break:

I think that is much too close to a logical expression. If I were to add a 
way to break out of an inner loop I'd introduce a fullblown (intra-function) 
goto.

So far I'm happy with generators; in my actual use cases something like

def g():
for i in range(10):
print(f'i: {i}')
for j in range(10):
print(f'\tj: {j}')
for k in range(10):
print(f'\t\tk: {k}')
yield i, j, k

for i, j, k in g():
if condition(i, j, k):
break

looks natural. Another option might be a dedicated exception:

class Break(Exception):
pass

try:
for i in range(10):
print(f'i: {i}')
for j in range(10):
print(f'\tj: {j}')
for k in range(10):
print(f'\t\tk: {k}')

if condition(i, j, k):
raise Break
except Break:
pass



-- 
https://mail.python.org/mailman/listinfo/python-list


Re: clever exit of nested loops

2018-09-26 Thread Chris Angelico
On Wed, Sep 26, 2018 at 5:56 PM  wrote:
>
> Hi
> Today I've added a couple of lines in my source code, and I'm very ashamed of 
> it.
> it "runs", and I know what it does (for now), but it's "too clever".
> I have "abused" the "else" clause of the loops to makes a break "broke" more 
> loops
>
>
> for i in range(10):
> print(f'i: {i}')
> for j in range(10):
> print(f'\tj: {j}')
> for k in range(10):
> print(f'\t\tk: {k}')
>
> if condition(i, j, k):
> break
>
> else:# if there weren't breaks in the inner loop,
> continue # then make anoter outer loop,
> break# else break also the outer one
>
> else:
> continue
> break
>
> the "magic" is in that repeated block... it's so convoluted to read... still 
> it's very useful to omit "signals" variables or the need to refactor it in a 
> function with an explicit return or other solutions.
>
> is there any chance to extends the python grammar to allow something like
>
>
> for i in range(10) and not break:
> print(f'i: {i}')
> for j in range(10) and not break:
> print(f'\tj: {j}')
> for k in range(10):
> print(f'\t\tk: {k}')
>
> if condition(i, j, k):
> break
>
>
> with the semantics of break a loop if an inner loop "broke"?
>

Hmm. I'm not enamoured of it.

My normal solution is to put the whole thing into a function and use
"return" to bail out. But sometimes that's not possible; sometimes you
do need a better solution. I'm not sure this one is it, though.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


clever exit of nested loops

2018-09-26 Thread vito . detullio
Hi
Today I've added a couple of lines in my source code, and I'm very ashamed of 
it.
it "runs", and I know what it does (for now), but it's "too clever".
I have "abused" the "else" clause of the loops to makes a break "broke" more 
loops


for i in range(10):
print(f'i: {i}')
for j in range(10):
print(f'\tj: {j}')
for k in range(10):
print(f'\t\tk: {k}')

if condition(i, j, k):
break

else:# if there weren't breaks in the inner loop, 
continue # then make anoter outer loop,
break# else break also the outer one

else:
continue
break

the "magic" is in that repeated block... it's so convoluted to read... still 
it's very useful to omit "signals" variables or the need to refactor it in a 
function with an explicit return or other solutions.

is there any chance to extends the python grammar to allow something like


for i in range(10) and not break:
print(f'i: {i}')
for j in range(10) and not break:
print(f'\tj: {j}')
for k in range(10):
print(f'\t\tk: {k}')

if condition(i, j, k):
break


with the semantics of break a loop if an inner loop "broke"?

 
-- 
https://mail.python.org/mailman/listinfo/python-list