Python Forum

Full Version: one time loop
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
i have a stack of if clause that all need to finish at the end of it all. doing it as an elif stack just doesn't work out, at least not cleanly, due to some nested if clauses in there. in assembly i would use a branch instruction. so what i might do in Python is wrap the whole thing in a one time loop and have a break statement at the end of all those if clauses (except the ones that do a return).

the big question is what is the best way in Python to do a one time loop? right now i coded for once in (1):. is there something better?
If it's only going to execute one time, why do you need a loop?
Got an Example?
what will the break statements do without the loop? the goal is to define where control ends up at when each if clause with a break reaches that break statement. a large bulk of the code i will release later (after completion and testing) is the stack of if clauses. without a break statement, they would run together unless i code it with elif. but i need other code among them, so elif won't work.

in other languages, i'd be using a branch instruction or a goto statement to do this.
Sorry, I don't understand. if there's no loop, then you won't need a break
but the break statements are needed, or something like it (but Python does not have a goto and i would not use it for this if it did). if i don't have a break how do all those if clauses (that are not all connected together, hence making elif not usable) join together at the end?

in C i had a macro named once defined to clearly make a one-time loop. but most people doing C or like code did:
    do {
        ...
    } while(0);
and GCC optimized it and understood the intention of all this. a few programmers just used a goto statement to join all the clauses at the end of them (and, thus, did not use break).

i need to create a wrapper around a big block of code that has several smaller blocks of code. each of these smaller blocks of code tests a condition and if the condition is met may execute some code, then needs to proceed to outside the big block of code. all these conditions of flow of control then join up at the end. if only these smaller blocks existed and nothing else, then this could be done by using elif for each smaller block (plain if for the first). the end of all these elifs (maybe also with an else at the end) would be where the flow of control all joins up. another way to do this is with deeply nested if/else. but the depth of this nesting can get quite extreme and make the code hard to read. the 3rd way to do this is to have a sequence of plain if statements with an escape method like a goto or if surrounded by a loop, and a break statement instead of a goto.

genuine examples would have to be very large to avoid someone suggesting the (ugly) deeply nested if/else. this is one reason why i am not ready to post a use-case.

i already explained that i can (and will) code this in Python as a one-time loop and will use for once in (1): if no better code is shown to me. but if you guys have never seen this kind of problem, i wonder if you have ever dealt with largely complex logic. i am wondering if maybe Python might have a nice clean way to do this.
(Jul-25-2018, 09:14 PM)Skaperen Wrote: [ -> ]what will the break statements do without the loop?

Then you'll get a SyntaxError.
You are only allowed to use the continue/break statement inside loops.
In functions you can use also return, to break out of a loop.

Additionally you have the possibility to use else in for-loops. In this case the else block is only executed, if the loop finishes. Today I've written code, which uses this control flow.

def find_and_remove(sequence, **kwargs):
    for element in sequence:
        if all(element.get(key) == kwargs.get(key) for key in kwargs):
            result = element
            # break out of the loop
            # the else block is not executed in this case.
            break
    else:
        # if the loop finishes, the function returns explicit None
        return None
    sequence.remove(result)
    # the result is only returned, a match was found
    return result
Quote:the goal is to define where control ends up at when each if clause with a break reaches that break statement.

If I understood it right, you want to have some branches inside a loop, which decides to break out of this loop. Yes, this is possible and often used. In my example this is used.

Each block in Python has it's own scope (maybe there are corner cases).
When you use a continue/break statement in nested scopes (eg. nested loops and other scopes),
it bubbles up, until it reaches the loop.


def foo():
    for a in range(20):
        for b in range(10):
            for c in range(5):
                with something() as bar:
                    for line in bar:
                        if 'foo' in line:
                            break
                            # this statement will break the
                            # for line in bar: loop
If you want to break out of the loop for b in range(10) you can solve this also.
This example is not the final solution.

def foo():
    for a in range(20):
        for b in range(10):
            # we want to break out of this loop if a condition is true
            for c in range(5):
                with something(a, b, c) as bar:
                    for line in bar:
                        if 'foo' in line:
                            break
                            # this statement will break the
                            # for line in bar: loop
                        elif 'bar' in line:
                            # if this block is executed, we want to break out of the
                            # loop: for b in range(10)
I guess it's better to refactor this code a little bit. We can use functions to make it easier for us to control the flow and still have an overview what's going on.

def do_something(*args)
    with something(*args) as bar:
        for line in bar:
            if 'foo' in line:
                return True
            elif 'bar' in line:
                return False

def abc_range():
    result = True
    for a in range(20):
        for b in range(10):
            if not result:
                # this breaks out of the b-loop
                break
            for c in range(5):
                result = do_something(a, b, c)
                # now the result is set and we need to break
                # out of the c-loop, where the b-loop continues
                if not result:
                    break
I guess with more effort you can avoid deep nested loops with if-branches.

Quote:in other languages, i'd be using a branch instruction or a goto statement to do this.
Using goto in other languages, leads to unreadable code and often in unpredictable code.
In High-Level languages you'll not see any use of goto.
(Jul-26-2018, 01:29 AM)DeaD_EyE Wrote: [ -> ]If I understood it right, you want to have some branches inside a loop, which decides to break out of this loop. Yes, this is possible and often used. In my example this is used.
yes, with all of them branching to the same place which means i only need one such loop.

(Jul-26-2018, 01:29 AM)DeaD_EyE Wrote: [ -> ]Each block in Python has it's own scope (maybe there are corner cases).
When you use a continue/break statement in nested scopes (eg. nested loops and other scopes),
it bubbles up, until it reaches the loop.
i won't be using continue. the only nesting i'll need is one layer of if in one layer of loop. there will be many of those if blocks, but they will not be nested in each other.

i'm skipping quoting a lot of your code because i am not using nested loops for this and so do not feel that code applies to what i am doing.

one loop, one time through, at most. perhaps one of the many breaks will cut it short.

(Jul-26-2018, 01:29 AM)DeaD_EyE Wrote: [ -> ]I guess with more effort you can avoid deep nested loops with if-branches.

i will avoid nested loops by having only one.

(Jul-26-2018, 01:29 AM)DeaD_EyE Wrote: [ -> ]Using goto in other languages, leads to unreadable code and often in unpredictable code.
In High-Level languages you'll not see any use of goto.
not always. there are cases where a carefully placed goto can make better code. what i am doing today might be if i were doing it in C. but i could also do it with break statements all wrapped in one single big do { } while(0); loop.

in Python, i'm more limited. there is no goto and no equivalent to do { } while(0); that i am aware of. so i expect to do something like:
    for once in (1):
        if condition-0:
            ...# code for condition-0:
            break
        ...# some intervening code #0
        if condition-1:
            ...# code for condition-1:
            break
        if condition-2:
            ...# code for condition-2:
            break
        if condition-3:
            ...# code for condition-3:
            break
        ...# some intervening code #1
        if condition-4:
            ...# code for condition-4:
            break
        if condition-5:
            ...# code for condition-5:
            break
        if condition-6:
            ...# code for condition-6:
            break
        ...# some intervening code #2
        if condition-7:
            ...# code for condition-7:
            break
        if condition-8:
            ...# code for condition-8:
            break
        if condition-9:
            ...# code for condition-9:
            break
        ...# some intervening code #3
        if condition-10:
            ...# code for condition-10:
            break
        if condition-11:
            ...# code for condition-11:
            break
        if condition-12:
            ...# code for condition-12:
            break
        ...# some intervening code #4
        if condition-13:
            ...# code for condition-13:
            break
        if condition-14:
            ...# code for condition-14:
            break
        if condition-15:
            ...# code for condition-15:
            break
        ...# some intervening code #5
        if condition-16:
            ...# code for condition-16:
            break
        if condition-17:
            ...# code for condition-17:
            break
        if condition-18:
            ...# code for condition-18:
            break
        ...# some intervening code #6
        if condition-19:
            ...# code for condition-19:
            break
        if condition-20:
            ...# code for condition-20:
            break
        if condition-21:
            ...# code for condition-21:
            break
        ...# some intervening code #7
        if condition-22:
            ...# code for condition-22:
            break
        if condition-23:
            ...# code for condition-23:
            break
        if condition-24:
            ...# code for condition-24:
            break
        ...# some intervening code #8
        if condition-25:
            ...# code for condition-25:
            break
        if condition-26:
            ...# code for condition-26:
            break
    ...# flow of control comes here after any break
the above is the way i'll be doing it. the above is fictional code of the same style. all i asked for is a better way to code that loop. the one first line is not saying what i am doing very well.

FYI the Linux kernel has thousands of gotos in it. Linus is an advocate for using gotos. and i have written code with gotos. maybe i'll have time to go dig it up.
(Jul-26-2018, 12:53 AM)Skaperen Wrote: [ -> ]if i don't have a break how do all those if clauses (that are not all connected together, hence making elif not usable) join together at the end?
Write a function?
And if they are not connected, why do they need to go to the same place?

(Jul-26-2018, 12:53 AM)Skaperen Wrote: [ -> ]i need to create a wrapper around a big block of code that has several smaller blocks of code. each of these smaller blocks of code tests a condition and if the condition is met may execute some code, then needs to proceed to outside the big block of code. all these conditions of flow of control then join up at the end.
Yep, sounds like a function to me.
there are 3 phases. the first is to check the arguments for types and errors and convert the various types to a common form (a list or tuple of ints), in a few cases it does a recursive call to itself and returns instead of going on to phase 2. the one-time loop only applies to phase 1. phase 3 takes that common form and returns the data to the caller in a form much like what it was called with. there are 4 of these, each for different kinds of data conversion. but i can't just make a simple common pattern since the data setup does vary somewhat with the type of conversion being done. these conversions are unicode to utf8, utf8 to unicode (because what python3 has is too limited), and encode+decode of variant escape sequences (a lot more than what python provides). there are somother data conversions i'm considering.

yes, there really are other ways to organize this. but maintaining a single direction of flow and avoiding extreme nesting depth helps people see what is going on. the way i am doing it meets my goal.