David Metcalfe
David Metcalfe

Reputation: 2411

Indentation in Python not always necessary?

I came across a piece of code (simplified for the question) structured like so:

while True:
    if x == y: break

My understanding of Python thus far is that the interpreter is highly dependent on tabs/spaces to understand the contents of things like loops and conditionals, but the above code style runs without issue, suggesting this isn't quite true.

Can someone explain the nuance?

Upvotes: 2

Views: 1000

Answers (4)

abarnert
abarnert

Reputation: 365717

The full details are explained in Compound Statements in the reference docs. But as a brief summary:

Any "compound statement", like if can take either an indented suite of statements, or an inline simple statement list.*

So, what's the difference between these?

if x == y:
    break

if x == y: break

Really, nothing, except that the first is usually considered more readable and idiomatic. (PEP 8, the official style guide, says the second form is "generally discouraged", but "sometimes it's okay to put an if/for/while with a small body on the same line".)**

These have the exact same semantics, performance, etc. They'll even compile to the exact same bytecode. There is a small syntactic difference, but it only affects which error messages you get if you embed these in various illegal constructs.


So, can you put something more complicated than break there?

Yes. Notice that it's a simple statement list. That means you can have multiple simple statements, separated by semicolons:

if x == y: print('Hey!'); x = -x; break

However, this is incredibly bad style. Unless you're trying to win a code-golf competition, don't do that.

But there are limits, too. Notice that it's a simple statement list. That means no compound statements. This is illegal:

if x == y: while True: print('loopy')

You can see the full list of simple statements here.


* An inline statement list is still considered a suite in the official grammar. But in loose discussion, suite more often means just the indented block alternative, not the inline alternative.

** In my experience, the most common place to see this in code by experienced devs is actually one of the places PEP 8 says to never do it: a class with a bunch of empty functions may have them on one line, like def spam(self): pass. That can make them hard to paste into the interactive interpreter, which is probably why PEP 8 says to never do it.

Upvotes: 4

user1129665
user1129665

Reputation:

Indentation here is not required because your have simple_stmt, break, in the if's suite:

...
if_stmt      ::=  "if" expression ":" suite
                 ("elif" expression ":" suite)*
                 ["else" ":" suite]
...
suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement     ::=  stmt_list NEWLINE | compound_stmt
...
stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]
...

In this case indentation is not required.

You can do this only with simple statements,like return or break, but you can't have a compound statements, if like while, without indentation .

Upvotes: 2

dom0
dom0

Reputation: 7486

In Python you can always replace an intended block with a single line if the block consists only of a single statement.

E.g.

def f(x): return x

def f(x):
    return x

are equivalent. The same is true for any other block-expecting syntax in Python:

  • if, else, elif, for, while, def, class, ...

Upvotes: 1

ssm
ssm

Reputation: 5373

Thats the difference between a statemment and a compound statement. For example, in C you might do something like

for(i=0; i<10; i++) printf("something");

or

for(i=0; i<10; i++) {printf("something");}

The for loop just executes a statement. However, when you include more than one statements within curly braces, like for example,

for(i=0; i<10; i++) {printf("something"); printf("something else");}

Then the entire thing within the curly braces is treated like one statement.

Its the same with Python ...

if x == y: 
    print 'abcd'   # These two statements are treated as 1 block
    break          # of statements 

If you just had one statement, you wouldnt need to define a block.

Upvotes: -1

Related Questions