569

I need to print some stuff only when a boolean variable is set to True. So, after looking at this, I tried with a simple example:

>>> a = 100
>>> b = True
>>> print a if b
  File "<stdin>", line 1
    print a if b
             ^
SyntaxError: invalid syntax  

Same thing if I write print a if b==True.

What am I missing here?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Ricky Robinson
  • 21,798
  • 42
  • 129
  • 185
  • 1
    possible duplicate of [Does Python have a ternary conditional operator?](http://stackoverflow.com/questions/394809/does-python-have-a-ternary-conditional-operator) – kenorb May 02 '15 at 16:55
  • 7
    Good question, complex answers... a straight one would be "the else part is mandatory". – mins Aug 07 '18 at 17:40
  • A good thing to note is that the if **expression** works in `lambda`, but **not** the one-line statement. – Ginger Mar 13 '21 at 01:14
  • @mins the accepted answer seems pretty straightforward to me. For a question this important, the top answers should include that kind of information. – Karl Knechtel Sep 27 '22 at 21:47
  • ... That is two ways of saying the same thing, and the way in the question does a better job of *justifying* the requirement. The reason expressions have to evaluate to a value (i.e., that being "equal to `void` is meaningless) is because "expressions" are exactly those things whose result can be assigned. – Karl Knechtel Sep 28 '22 at 08:12
  • @KarlKnechtel: I added an answer to clarify. – mins Sep 28 '22 at 09:40

15 Answers15

1054

Python does not have a trailing if statement.

There are two kinds of if in Python:

  1. if statement:

    if condition: statement
    if condition:
        block
    
  2. if expression (introduced in Python 2.5)

    expression_if_true if condition else expression_if_false
    

And note, that both print a and b = a are statements. Only the a part is an expression. So if you write

print a if b else 0

it means

print (a if b else 0)

and similarly when you write

x = a if b else 0

it means

x = (a if b else 0)

Now what would it print/assign if there was no else clause? The print/assignment is still there.

And note, that if you don't want it to be there, you can always write the regular if statement on a single line, though it's less readable and there is really no reason to avoid the two-line variant.

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
  • 1
    I think that `if condition: statement` does not work in case of multiline statements. – Val Nov 08 '13 at 12:57
  • Yes, but you don't need to use if, simply use boolean logic like I show below in my examples. – Eduardo Mar 19 '14 at 17:16
  • 3
    @JanHudec If Python doesn't have a trailing `if`, then why does this work: [`print [i for i in range(10) if i%2]`](https://repl.it/BLMh)? I wish they'd allow it outside of comprehensions... – mbomb007 Sep 26 '15 at 22:13
  • 4
    @mbomb007, that is not a trailing if *statement* either. It is simply part of the list (or generator) comprehension. Note that the thing before the if is not a statement, it is two expressions with `for` between them. – Jan Hudec Sep 28 '15 at 17:41
  • Thanks, that helped me a lot. Would print ("a " + (id+ "_" if id else "") + " b") be considered a good solution if I want to ad an "id_" to a string if id is not none? – Alexander von Wernherr Dec 16 '16 at 10:26
  • 2
    @AlexandervonWernherr, yes, that sounds reasonable. – Jan Hudec Dec 16 '16 at 12:00
  • Can anybody help me understand why b=a is a statement and not an expression? – Karan Singh May 21 '17 at 07:30
  • @KaranSingh, because python grammar defines it that way. – Jan Hudec May 21 '17 at 12:07
  • can the else part be omitted? To write like print a if a – Apurva Kunkulol Jul 05 '17 at 13:45
  • @ApurvaKunkulol, would you be so kind and *read the question again*? It shows precisely that syntax—and the syntax error it produces. Ergo, no, it can't. – Jan Hudec Jul 05 '17 at 16:35
  • I ended up doing something like `print("reason why I do nothing") if not_good_reason else do_something()` – Gavin Palmer Mar 09 '18 at 14:10
  • It's worth noting that 'else' is required. It would be convenient to simply use 'if' in some cases (e.g. c += a if b), but alas. – Juniper Jones Jun 11 '18 at 20:16
  • 1
    @KaranSingh, the `a=b` not being an expression is a helpful syntactic device in Python, and learnt from other languages (C) where assignment and testing could be mingled and mixed up. – CodeMantle Feb 12 '19 at 18:05
136

Inline if-else EXPRESSION must always contain else clause, e.g:

a = 1 if b else 0

If you want to leave your 'a' variable value unchanged - assing old 'a' value (else is still required by syntax demands):

a = 1 if b else a

This piece of code leaves a unchanged when b turns to be False.

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
Rostyslav Dzinko
  • 39,424
  • 5
  • 49
  • 62
35

The 'else' statement is mandatory. You can do stuff like this :

>>> b = True
>>> a = 1 if b else None
>>> a
1
>>> b = False
>>> a = 1 if b else None
>>> a
>>> 

EDIT:

Or, depending of your needs, you may try:

>>> if b: print(a)
Alexis Huet
  • 755
  • 4
  • 11
24

If you don't want to from __future__ import print_function you can do the following:

a = 100
b = True
print a if b else "",  # Note the comma!
print "see no new line"

Which prints:

100 see no new line

If you're not aversed to from __future__ import print_function or are using python 3 or later:

from __future__ import print_function
a = False
b = 100
print(b if a else "", end = "")

Adding the else is the only change you need to make to make your code syntactically correct, you need the else for the conditional expression (the "in line if else blocks")

The reason I didn't use None or 0 like others in the thread have used, is because using None/0 would cause the program to print None or print 0 in the cases where b is False.

If you want to read about this topic I've included a link to the release notes for the patch that this feature was added to Python.

The 'pattern' above is very similar to the pattern shown in PEP 308:

This syntax may seem strange and backwards; why does the condition go in the middle of the expression, and not in the front as in C's c ? x : y? The decision was checked by applying the new syntax to the modules in the standard library and seeing how the resulting code read. In many cases where a conditional expression is used, one value seems to be the 'common case' and one value is an 'exceptional case', used only on rarer occasions when the condition isn't met. The conditional syntax makes this pattern a bit more obvious:

contents = ((doc + '\n') if doc else '')

So I think overall this is a reasonable way of approching it but you can't argue with the simplicity of:

if logging: print data
Noelkd
  • 7,686
  • 2
  • 29
  • 43
18

You can write an inline ternary operator like so:

sure = True

# inline operator
is_true = 'yes' if sure else 'no'

# print the outcome
print(is_true)
Yaakov Bressler
  • 9,056
  • 2
  • 45
  • 69
Mussa Charles
  • 659
  • 7
  • 10
15

This can be done with string formatting. It works with the % notation as well as .format() and f-strings (new to 3.6)

print '%s' % (a if b else "")

or

print '{}'.format(a if b else "")

or

print(f'{a if b else ""}')
Community
  • 1
  • 1
Eric Ed Lohmar
  • 1,832
  • 1
  • 17
  • 26
  • This has nothing to do with formatting; you could just do `print a if b else ""`. Which is exactly what Noelkd's answer does. – melpomene Feb 24 '17 at 15:56
  • @melpomene but printing "" ads a new line, that can be avoided using `print "",` (colon) for Python2, and using `print("", end="")` for Python3. – m3nda May 29 '17 at 18:39
14

You can use:

print (1==2 and "only if condition true" or "in case condition is false")

Just as well you can keep going like:

print (1==2 and "aa" or ((2==3) and "bb" or "cc"))

Real world example:

>>> print ("%d item%s found." % (count, (count!=1 and 's' or '')))
1 item found.
>>> count = 2
>>> print ("%d item%s found." % (count, (count!=1 and 's' or '')))
2 items found.
Eduardo
  • 7,631
  • 2
  • 30
  • 31
13

Since 2.5 you can use equivalent of C’s ”?:” ternary conditional operator and the syntax is:

[on_true] if [expression] else [on_false]

So your example is fine, but you've to simply add else, like:

print a if b else ''
Community
  • 1
  • 1
kenorb
  • 155,785
  • 88
  • 678
  • 743
6

For your case this works:

a = b or 0

Edit: How does this work?

In the question

b = True

So evaluating

b or 0

results in

True

which is assigned to a.

If b == False?, b or 0 would evaluate to the second operand 0 which would be assigned to a.

  • 3
    Ugliness and errorproneness of this expression is the reason why we have conditional expression in the first place. – Jan Hudec Aug 09 '12 at 09:41
6

Try this . It might help you

a=100
b=True

if b:
   print a
Duncan
  • 92,073
  • 11
  • 122
  • 156
SkariaArun
  • 219
  • 1
  • 13
6

You're simply overcomplicating.

if b:
   print a
Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
Nande
  • 409
  • 1
  • 6
  • 11
5
print a if b
File "<stdin>", line 1
    print a if b
         ^
SyntaxError: invalid syntax  

Answer

If your print statement must print an empty line when the expression is false, the correct syntax is:

print(a if b else '')

The reason is you're using the conditional expression which has two mandatory clauses, one when b is true preceding if, one when b is false following else.

Both clauses are themselves expressions. The conditional expression is also called the ternary operator, making it clear it operates on three elements, a condition and two expressions. In your code the else part is missing.

However I guess your idea was not to print an empty line when the expression was false, but to do nothing. In that case you have to use print within a conditional statement, in order to condition its execution to the result of the evaluation of b.


Details: Expression vs. statement

The conditional statement can be used without the else part:

  • The if statement is a compound statement with further instructions to execute depending on the result of the condition evaluation.

  • It is not required to have an else clause where the appropriate additional instructions are provided. Without it, when the condition is false no further instructions are executed after the test.

  • The conditional expression is an expression. Any expression must be convertible to a final value, regardless of the subsequent use of this value by subsequent statements (here the print statement).

  • Python makes no assumption about what should be the value of the expression when the condition is false.

You could have used an if statement this way:

if b: print(a)

Note the difference:

  • There is no instructions executed by the if statement when the condition is false, nothing is printed because print is not called.

  • In a print statement with a conditional expression print(a if b else ''), print is always executed. What it prints is the if conditional expression. This expression is evaluated prior to executing the print statement. So print outputs an empty line when the condition is false.


Note your other attempt print(a if b==True) is just equivalent to the first one.

Since b==True is syntactically equivalent to b, I guess Python interpreter just replaces the former by the latter before execution. Your second attempt likely comes down to a repeat of the first one.

mins
  • 6,478
  • 12
  • 56
  • 75
3

You always need an else in an inline if:

a = 1 if b else 0

But an easier way to do it would be a = int(b).

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
2

hmmm, you can do it with a list comprehension. This would only make sense if you had a real range.. but it does do the job:

print([a for i in range(0,1) if b])

or using just those two variables:

print([a for a in range(a,a+1) if b])
-2

Well why don't you simply write:

if b:
    print a
else:
    print 'b is false'
IcyFlame
  • 5,059
  • 21
  • 50
  • 74