Python
Programming
Control Flow
Goto
Code Structure

Is there a label/goto in Python?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Python does not have a built-in goto statement, and that is intentional. The language is designed around structured control flow with loops, functions, exceptions, and explicit state handling, because those tools make code easier to understand than arbitrary jumps.

Why Python Avoids goto

A true goto lets execution jump to a label almost anywhere in a function. That flexibility can make code hard to reason about because the reader has to track possible jumps instead of reading the function top to bottom.

Python instead emphasizes:

  • 'if, elif, and else'
  • 'for and while'
  • 'break and continue'
  • 'return'
  • exceptions for non-local exits

So the real Python question is usually not “how do I emulate goto,” but “which structured tool fits the control flow I need.”

Use Loop Control for Many Goto-Like Cases

Many supposed goto needs are really about skipping work or leaving a loop early.

python
1def process_commands(commands):
2    output = []
3    i = 0
4
5    while i < len(commands):
6        cmd = commands[i]
7
8        if cmd == "skip":
9            i += 2
10            continue
11
12        if cmd == "stop":
13            break
14
15        output.append(f"run:{cmd}")
16        i += 1
17
18    return output
19
20
21print(process_commands(["a", "skip", "b", "c", "stop", "d"]))

This is clearer than simulating jumps with flags or unnatural control structures.

Use Functions and Early Returns

Another classic goto use case is jumping to a shared exit path. In Python, the usual solution is to put the logic in a function and return as soon as the answer is known.

python
1def validate_order(order):
2    if "id" not in order:
3        return False
4    if order.get("status") == "cancelled":
5        return False
6    if order.get("total", 0) <= 0:
7        return False
8    return True
9
10
11print(validate_order({"id": "A100", "status": "new", "total": 49.0}))

This is direct, testable, and much easier to maintain than a jump-based exit pattern.

Use Exceptions for Non-Local Failure Paths

If the real intent is to abandon a deeper stack of calls when something goes wrong, exceptions are the structured Python answer.

python
1class InvalidPayloadError(Exception):
2    pass
3
4
5def parse_payload(payload):
6    if "count" not in payload:
7        raise InvalidPayloadError("count missing")
8
9    value = int(payload["count"])
10    if value < 0:
11        raise InvalidPayloadError("count cannot be negative")
12
13    return value
14
15
16try:
17    print(parse_payload({"count": "4"}))
18except InvalidPayloadError as exc:
19    print("parse failed:", exc)

That is how Python expresses many of the non-local exit paths that lower-level code might express with labels.

Use a State Machine When the Flow Really Has Named States

If the control flow truly jumps among named states, a state machine is often the right abstraction.

python
1def run_state_machine(start):
2    state = start
3
4    transitions = {
5        "start": lambda: "loading",
6        "loading": lambda: "ready",
7        "ready": lambda: "done",
8    }
9
10    while state in transitions:
11        print("state", state)
12        state = transitions[state]()
13
14    return state
15
16
17print(run_state_machine("start"))

This makes the transitions explicit instead of hiding them in ad hoc jumps.

Avoid Goto Emulation Tricks

There have been experiments that emulate goto in Python through decorators, tracing hooks, or bytecode tricks. They are not idiomatic, they surprise other developers, and they work against the normal structure of the language.

If your code feels like it needs goto, it usually points to one of these deeper problems:

  • the function is too large
  • state transitions are implicit instead of modeled directly
  • loop logic is unclear
  • responsibilities are mixed together

The missing feature is often not goto. The missing feature is a better structure.

Common Pitfalls

The most common mistake is replacing goto with a maze of boolean flags and ending up with code that is just as confusing.

Another pitfall is using exceptions for ordinary loop control when break, continue, or return would be clearer.

Developers also often keep one giant function when splitting it into smaller functions would eliminate the jump-like need entirely.

Finally, avoid clever emulation libraries unless you are deliberately experimenting. They are not a normal Python solution.

Summary

  • Python has no built-in label or goto statement.
  • Most goto use cases are better expressed with loop control, early returns, exceptions, or state machines.
  • Early returns are the clean replacement for many shared-exit patterns.
  • Exceptions are appropriate for non-local error exits.
  • If you think you need goto, the code usually needs restructuring instead.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.