Is there a label/goto in Python?

PythonGoto

Python Problem Overview


Is there a goto or any equivalent in Python to be able to jump to a specific line of code?

Python Solutions


Solution 1 - Python

No, Python does not support labels and goto. It's a (highly) structured programming language.

Solution 2 - Python

Python offers you the ability to do some of the things you could do with a goto using first class functions. For example:

void somefunc(int a)
{
    if (a == 1)
        goto label1;
    if (a == 2)
        goto label2;

    label1:
        ...
    label2:
        ...
}

Could be done in Python like this:

def func1():
    ...

def func2():
    ...

funcmap = {1 : func1, 2 : func2}

def somefunc(a):
    funcmap[a]()  #Ugly!  But it works.

Granted, that isn't the best way to substitute for goto. But without knowing exactly what you're trying to do with the goto, it's hard to give specific advice.

@ascobol:

Your best bet is to either enclose it in a function or use an exception. For the function:

def loopfunc():
    while 1:
        while 1:
            if condition:
                return

For the exception:

try:
    while 1:
        while 1:
            raise BreakoutException #Not a real exception, invent your own
except BreakoutException:
    pass

Using exceptions to do stuff like this may feel a bit awkward if you come from another programming language. But I would argue that if you dislike using exceptions, Python isn't the language for you. :-)

Solution 3 - Python

I recently wrote a function decorator that enables goto in Python, just like that:

from goto import with_goto

@with_goto
def range(start, stop):
    i = start
    result = []

    label .begin
    if i == stop:
        goto .end

    result.append(i)
    i += 1
    goto .begin

    label .end
    return result

I'm not sure why one would like to do something like that though. That said, I'm not too serious about it. But I'd like to point out that this kind of meta programming is actual possible in Python, at least in CPython and PyPy, and not only by misusing the debugger API as that other guy did. You have to mess with the bytecode though.

Solution 4 - Python

I found this in the official python Design and History FAQ.

> Why is there no goto? > > You can use exceptions to provide a “structured goto” that even works > across function calls. Many feel that exceptions can conveniently > emulate all reasonable uses of the “go” or “goto” constructs of C, > Fortran, and other languages. For example:

class label(Exception): pass  # declare a label

try:
    ...
    if condition: raise label()  # goto label
    ...
except label:  # where to goto
    pass
... 

> This doesn’t allow you to jump into the middle of a loop, but that’s > usually considered an abuse of goto anyway. Use sparingly.

It's very nice that this is even mentioned in the official FAQ, and that a nice solution sample is provided. I really like python because its community is treating even goto like this ;)

Solution 5 - Python

To answer the @ascobol's question using @bobince's suggestion from the comments:

for i in range(5000):
    for j in range(3000):
        if should_terminate_the_loop:
           break
    else: 
        continue # no break encountered
    break

The indent for the else block is correct. The code uses obscure else after a loop Python syntax. See Why does python use 'else' after for and while loops?

Solution 6 - Python

A working version has been made: http://entrian.com/goto/.

Note: It was offered as an April Fool's joke. (working though)

# Example 1: Breaking out from a deeply nested loop:
from goto import goto, label

for i in range(1, 10):
    for j in range(1, 20):
        for k in range(1, 30):
            print i, j, k
            if k == 3:
                goto .end
label .end
print "Finished\n"

Needless to say. Yes its funny, but DONT use it.

Solution 7 - Python

It is technically feasible to add a 'goto' like statement to python with some work. We will use the "dis" and "new" modules, both very useful for scanning and modifying python byte code.

The main idea behind the implementation is to first mark a block of code as using "goto" and "label" statements. A special "@goto" decorator will be used for the purpose of marking "goto" functions. Afterwards we scan that code for these two statements and apply the necessary modifications to the underlying byte code. This all happens at source code compile time.

import dis, new

def goto(fn):
    """
    A function decorator to add the goto command for a function.

        Specify labels like so:
        label .foo

        Goto labels like so:
        goto .foo

        Note: you can write a goto statement before the correspnding label statement
    """
    labels = {}
    gotos = {}
    globalName = None
    index = 0
    end = len(fn.func_code.co_code)
    i = 0

    # scan through the byte codes to find the labels and gotos
    while i < end:
        op = ord(fn.func_code.co_code[i])
        i += 1
        name = dis.opname[op]

        if op > dis.HAVE_ARGUMENT:
            b1 = ord(fn.func_code.co_code[i])
            b2 = ord(fn.func_code.co_code[i+1])
            num = b2 * 256 + b1
            
            if name == 'LOAD_GLOBAL':
                globalName = fn.func_code.co_names[num]
                index = i - 1
                i += 2
                continue
                
            if name == 'LOAD_ATTR':
                if globalName == 'label':
                    labels[fn.func_code.co_names[num]] = index
                elif globalName == 'goto':
                    gotos[fn.func_code.co_names[num]] = index
                    
            name = None
            i += 2

    # no-op the labels
    ilist = list(fn.func_code.co_code)
    for label,index in labels.items():
        ilist[index:index+7] = [chr(dis.opmap['NOP'])]*7

    # change gotos to jumps
    for label,index in gotos.items():
        if label not in labels:
            raise Exception("Missing label: %s"%label)
        
        target = labels[label] + 7   # skip NOPs
        ilist[index] = chr(dis.opmap['JUMP_ABSOLUTE'])
        ilist[index + 1] = chr(target & 255)
        ilist[index + 2] = chr(target >> 8)

    # create new function from existing function
    c = fn.func_code
    newcode = new.code(c.co_argcount,
                       c.co_nlocals,
                       c.co_stacksize,
                       c.co_flags,
                       ''.join(ilist),
                       c.co_consts,
                       c.co_names,
                       c.co_varnames,
                       c.co_filename,
                       c.co_name,
                       c.co_firstlineno,
                       c.co_lnotab)
    newfn = new.function(newcode,fn.func_globals)
    return newfn


if __name__ == '__main__':
    
    @goto
    def test1():
        print 'Hello' 
        
        goto .the_end
        print 'world'
        
        label .the_end
        print 'the end'

    test1()

Hope this answers the question.

Solution 8 - Python

Python 2 & 3

pip3 install goto-statement

> Tested on Python 2.6 through 3.6 and PyPy.

Link: goto-statement


foo.py

from goto import with_goto

@with_goto
def bar():

    label .bar_begin

    ...

    goto .bar_begin

Solution 9 - Python

Labels for break and continue were proposed in PEP 3136 back in 2007, but it was rejected. The Motivation section of the proposal illustrates several common (if inelegant) methods for imitating labeled break in Python.

Solution 10 - Python

you can use User-defined Exceptions to emulate goto

example:

class goto1(Exception):
    pass   
class goto2(Exception):
    pass   
class goto3(Exception):
    pass   


def loop():
    print 'start'
    num = input()
    try:
        if num<=0:
            raise goto1
        elif num<=2:
            raise goto2
        elif num<=4:
            raise goto3
        elif num<=6:
            raise goto1
        else:
            print 'end'
            return 0
    except goto1 as e:
        print 'goto1'
        loop()
    except goto2 as e:
        print 'goto2'
        loop()
    except goto3 as e:
        print 'goto3'
        loop()

Solution 11 - Python

I was looking for some thing similar to

for a in xrange(1,10):
A_LOOP
    for b in xrange(1,5):
        for c in xrange(1,5):
            for d in xrange(1,5):
                # do some stuff
                if(condition(e)):
                    goto B_LOOP;

So my approach was to use a boolean to help breaking out from the nested for loops:

for a in xrange(1,10):
    get_out = False
    for b in xrange(1,5):
        if(get_out): break
        for c in xrange(1,5):
            if(get_out): break
            for d in xrange(1,5):
                # do some stuff
                if(condition(e)):
                    get_out = True
                    break

Solution 12 - Python

Though there isn't any code equivalent to goto/label in Python, you could still get such functionality of goto/label using loops.

Lets take a code sample shown below where goto/label can be used in a arbitrary language other than python.

String str1 = 'BACK'

label1:
    print('Hello, this program contains goto code\n')
    print('Now type BACK if you want the program to go back to the above line of code. Or press the ENTER key if you want the program to continue with further lines of code')
    str1 = input()

if str1 == 'BACK'
    {
        GoTo label1
    }
print('Program will continue\nBla bla bla...\nBla bla bla...\nBla bla bla...')

Now the same functionality of the above code sample can be achieved in python by using a while loop as shown below.

str1 = 'BACK'

while str1 == 'BACK':
        print('Hello, this is a python program containing python equivalent code for goto code\n')
        print('Now type BACK if you want the program to go back to the above line of code. Or press the ENTER key if you want the program to continue with further lines of code')
        str1 = input()
print('Program will continue\nBla bla bla...\nBla bla bla...\nBla bla bla...')

Solution 13 - Python

You can achieve it using nested methods inside python

def func1():
    print("inside func1")
    def inline():
        print("im inside")
    
    inline()
    
func1()

Solution 14 - Python

There is now. goto

I think this might be useful for what you are looking for.

Solution 15 - Python

When implementing "goto", one must first ask what a goto is. While it may seem obvious, most people don't think about how goto relates to function stacks.

If you perform a "goto" inside a function, you are, in effect, abandoning the function call stack. This is considered bad practice, because function stacks are designed with the expectation that you will continue where you left off, after delegating an intermediate task. This is why gotos are used for exceptions, and exceptions can be used to emulate goto, which i will explain.

Finite state machines are probably the best use case for goto, which most of the time are implemented in a kludgy way with loops and switch statements, but I believe that "top level" gotos, are the cleanest, most semantic way to implement finite state machines. In this case, you want to make sure, if you have more variables, they are globals, and don't require encapsulation. Make sure you first model your variable state space(which may be different from execution state, ie the finite state machine).

I believe there are legitimate design reasons to use goto, exception handling being the special case where mixing goto with functions makes sense. However, in most cases, you want to restrict yourself to "top level" goto, so you never call goto within a function, but only within a global scope.

The easiest way to emulate top level goto in modern languages, is to realize that top-level gotos, simply require global variables and an empty call stack. So to keep the call stack empty, you return whenever you call a new function. Here's an example to print the first n fibonacci numbers:

a = 0
b = 1
n = 100
def A():
    global a, b
    a = a + b
    n -= 1
    print(a)
    return B() if n > 0 else 0
def B():
    global a, b
    b = a + b
    n -= 1
    print(b)
    return A() if n > 0 else 0
A()

While this example may be more verbose than loop implementations, it is also much more powerful and flexible, and requires no special cases. It lets you have a full finite state machine. You could also modify this with a goto runner.

def goto(target):
    while(target) target = target()
def A():
    global a, b
    a = a + b
    print(a)
    return B
def B():
    global a, b
    b = a + b
    print(b)
    return A
goto(A)

To enforce the "return" part, you could write a goto function that simply throws an exception when finished.

def goto(target):
    target()
    throw ArgumentError("goto finished.")
def A():
    global a, b
    a = a + b
    print(a)
    goto(B)
def B()
    global a, b
    b = a + b
    print(b)
    goto(A)
goto(A)

So you see, a lot of this is overthinking, and a helper function that calls a function and then throws an error is all you need. You could further wrap it in a "start" function, so the error gets caught, but I don't think that's strictly necessary. While some of these implementations may use up your call stack, the first runner example keeps it empty, and if compilers can do tail call optimization, that helps as well.

Solution 16 - Python

I wanted the same answer and I didnt want to use goto. So I used the following example (from learnpythonthehardway)

def sample():
    print "This room is full of gold how much do you want?"
    choice = raw_input("> ")
    how_much = int(choice)
    if "0" in choice or "1" in choice:
        check(how_much)
    else:
        print "Enter a number with 0 or 1"
        sample()
        
def check(n):
    if n < 150:
        print "You are not greedy, you win"
        exit(0)
    else:
        print "You are nuts!"
        exit(0)

Solution 17 - Python

I have my own way of doing gotos. I use separate python scripts.

If I want to loop:

file1.py

print("test test")
execfile("file2.py")
a = a + 1

file2.py

print(a)
if a == 10:
   execfile("file3.py")
else:
   execfile("file1.py")

file3.py

print(a + " equals 10")

(NOTE: This technique only works on Python 2.x versions)

Solution 18 - Python

For a forward Goto, you could just add:

while True:
  if some condition:
    break
  #... extra code
  break # force code to exit. Needed at end of while loop
#... continues here

This only helps for simple scenarios though (i.e. nesting these would get you into a mess)

Solution 19 - Python

In lieu of a python goto equivalent I use the break statement in the following fashion for quick tests of my code. This assumes you have structured code base. The test variable is initialized at the start of your function and I just move the "If test: break" block to the end of the nested if-then block or loop I want to test, modifying the return variable at the end of the code to reflect the block or loop variable I'm testing.

def x:
  test = True
  If y:
     # some code
     If test:
            break
  return something

Solution 20 - Python

no there is an alternative way to implement goto statement

class id:
     def data1(self):
        name=[]
        age=[]   
        n=1
        while n>0:
            print("1. for enter data")
            print("2. update list")
            print("3. show data")
            print("choose what you want to do ?")
            ch=int(input("enter your choice"))
            if ch==1:    
                n=int(input("how many elemet you want to enter="))
                for i in range(n):
                    name.append(input("NAME "))
                    age.append(int(input("age "))) 
            elif ch==2:
                name.append(input("NAME "))
                age.append(int(input("age ")))
            elif ch==3:
                try:
                    if name==None:
                        print("empty list")
                    else:
                        print("name \t age")
                        for i in range(n):
                            print(name[i]," \t ",age[i])
                        break
                except:
                    print("list is empty")
            print("do want to continue y or n")
            ch1=input()
            if ch1=="y":
                n=n+1
            else:
                print("name \t age")
                for i in range(n):
                    print(name[i]," \t ",age[i])
                n=-1
p1=id()
p1.data1()  

Solution 21 - Python

I think while loop is alternate for the "goto_Statement". Because after 3.6 goto loop is not working anymore. I also write an example of the while loop.

str1 = "stop"
while str1 == "back":
    var1 = int(input(" Enter Ist Number: "))
    var2 = int(input(" Enter 2nd Number: "))
    var3 = print("""  What is your next operation
                      For Addition   Press And Enter : 'A'
                      For Muliplt    Press And Enter : 'M'
                      For Division   Press And Enter : 'D'
                      For Subtaction Press And Enter : 'S' """)

    var4 = str(input("For operation press any number : "))
    if(var1 == 45) and (var2 == 3):
        print("555")
    elif(var1 == 56) and (var2 == 9):
        print("77")
    elif(var1 == 56) and (var2 == 6):
        print("4")
    else:
        if(var4 == "A" or "a"):
            print(var1 + var2)
        if(var4 == "M" or "m"):
            print(var1 * var2)
        if(var4 == "D" or "d"):
            print(var1 / var2)
        if(var4 == "S" or "s"):
            print(var1 - var2)

    print("if you want to continue then type  'stop'")

    str1 = input()
print("Strt again")    

Solution 22 - Python

I solved this problem with functions. Only thing I did was change labels with functions. Here is a very basic code:

def goto_holiday(): #label: holiday
        print("I went to holiday :)")
    
def goto_work(): #label: work
    print("I went to work")
salary=5000
if salary>6000:
    goto_holiday()
else:
    goto_work()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser46646View Question on Stackoverflow
Solution 1 - PythonunwindView Answer on Stackoverflow
Solution 2 - PythonJason BakerView Answer on Stackoverflow
Solution 3 - PythonSebastian NoackView Answer on Stackoverflow
Solution 4 - PythonklaasView Answer on Stackoverflow
Solution 5 - PythonjfsView Answer on Stackoverflow
Solution 6 - PythonharmvView Answer on Stackoverflow
Solution 7 - PythonRabih KodeihView Answer on Stackoverflow
Solution 8 - PythonMarco D.G.View Answer on Stackoverflow
Solution 9 - PythonBill the LizardView Answer on Stackoverflow
Solution 10 - PythonxavierskipView Answer on Stackoverflow
Solution 11 - PythonyaitloutouView Answer on Stackoverflow
Solution 12 - PythonSomannaView Answer on Stackoverflow
Solution 13 - PythonNikhil DineshView Answer on Stackoverflow
Solution 14 - PythonanchoView Answer on Stackoverflow
Solution 15 - PythonderekmcView Answer on Stackoverflow
Solution 16 - Pythonsan1512View Answer on Stackoverflow
Solution 17 - PythonAnonaguyView Answer on Stackoverflow
Solution 18 - PythonJGFMKView Answer on Stackoverflow
Solution 19 - PythonChris RoganView Answer on Stackoverflow
Solution 20 - PythonPython ExpertsView Answer on Stackoverflow
Solution 21 - PythonHamza TanveerView Answer on Stackoverflow
Solution 22 - PythonBARIS KURTView Answer on Stackoverflow