Pythoner
Pythoner

Reputation: 5585

Why doesn't python support 'pass' in ternary expression?

I've written the following code which results in SyntaxError: invalid syntax:

self.vec.append(v1) if v1 else pass

I thought it would do the same thing as this code:

if v1:
    self.vec.append(v1)

Just wondering why python does not support this syntax while it supports:

self.vec.append(v1) if v1 else 0 

Upvotes: 5

Views: 338

Answers (3)

Mateen Ulhaq
Mateen Ulhaq

Reputation: 27201

A ternary statement is of the form:

<object> = <object> if <boolean expression> else <object>

But pass is not an <object>!

pass is a keyword, and it is used for flow control (NOOP). For instance, you can't assign pass to a variable:

>>> x = pass
Syntax Error

In the same way, you can't assign other keywords such as while to variables either:

>>> x = while
Syntax Error

Also, append returns None, which is certainly an <object>.

>>> print([].append(420))
None

Upvotes: 6

Code-Apprentice
Code-Apprentice

Reputation: 83537

One critical thing to keep straight here is that your first line of code is an expression and the second code snippet is a statement. An expression must valuate to a value while a statement is just a command that doesn't have a value.

Upvotes: 1

abarnert
abarnert

Reputation: 365787

The real issue here is that you shouldn't be writing either of these.1

self.vec.append(v1) if v1 else pass is illegal because pass is a statement, not an expression, and you can't put statements inside expressions.

self.vec.append(v1) if v1 else 0 is legal, because 0 is an expression.

But just because it's legal doesn't mean it's code you should ever write.

The point of the if expression is that it's an expression, so it (a) has a value that you can use, and (b) can be used in larger expressions.

You aren't using the value of self.vec.append(v1) (which is None), or the value of 0 (which is of course 0). You're just evaluating the first one for its side-effects and the second one as a workaround to fight against the language's syntax.

You're also not putting the expression inside another expression; you're just using it as an expression statement.

The way to write this is simple:

if v1:
    self.vec.append(v1)
else:
    pass

But of course you don't need an else clause here, so you can just write this as:

if v1:
    self.vec.append(v1)

Or, if you're desperate to save space:

if v1: self.vec.append(v1)

Sometimes it's worth sacrificing readability for performance, or occasionally even for brevity. But your attempt to abuse an if expression for its side effects is slower (especially in the false case—a jump and evaluating a literal just to discard it may be fast, but it's not nearly as fast as doing nothing at all). And it's much longer.


1. In fact, the worry that people would try to write code like this, even though there's absolutely no reason to, was the main argument against PEP 308, the proposal to add this feature. The PEP passed only because anyone who'd be silly enough to try to write code like this is going to write Perl instead of Python anyway.

Upvotes: 2

Related Questions