Re: clever exit of nested loops
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
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
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
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
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
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
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
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
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