Reputation: 2411
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
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
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
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:
Upvotes: 1
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