3

Why is this code

for i in range(10):
    if i == 5: print i

valid while the compound statement (I know that PEP 8 discourages such coding style)

for i in range(10): if i == 5: print i

is not?

Franck Dernoncourt
  • 77,520
  • 72
  • 342
  • 501

3 Answers3

7

This is because python has strict rules about indentation being used to represent blocks of code and by putting an for followed by an if, you create ambiguous indentation interpretations and thus python does not allow it.

For python, you can put as many lines as you want after a if statement:

if 1==1: print 'Y'; print 'E'; print 'S'; print '!';

as long as they all have the same indentation level, i.e., no if, while, for as they introduce a deeper indentation level.

Hope that helps

sshashank124
  • 31,495
  • 9
  • 67
  • 76
  • This is documented in the `Python Language Reference` document under `Compound statements` (https://docs.python.org/3/reference/compound_stmts.html): "A suite can be one or more semicolon-separated simple statements on the same line as the header, following the header’s colon, or it can be one or more indented statements on subsequent lines. Only the latter form of suite can contain nested compound statements [...]". – Ned Deily May 04 '14 at 03:18
6

The reason why you cannot is because the language simply doesn't support it:

for_stmt ::=  "for" target_list "in" expression_list ":" suite
              ["else" ":" suite]

It has been suggested many times on the Python mailing lists, but has never really gained traction because it's already possible to do using existing mechanisms...

Such as a filtered generator expression:

for i in (i for i in range(10) if i == 5):
    ...

The advantage of this over the list comprehension is that it doesn't generate the entire list before iterating over it.

Matthew Trevor
  • 14,354
  • 6
  • 37
  • 50
  • Including an `if` clause with a `for` statement is not really what the OP is asking about. Disallowing multiple compound statements on the same line is a more general issue. – Ned Deily May 04 '14 at 03:23
1

using list comprehension:

In [10]: [x for x in range(10) if x ==5][0]
Out[10]: 5
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • The OP was asking a "why" question, I don't see how your answer helps. – Akavall May 04 '14 at 00:45
  • You don't see any relation? – Padraic Cunningham May 04 '14 at 00:47
  • I don't, the answer has to do with indentation rules, as explained by @sshashank124. As OP question stands, they were looking for an explanation of why certain code does not work, not a hacky 1-liner that does something similar. Your code is different, OP only intends to print an element, not create a list as you do. – Akavall May 04 '14 at 00:54