-2

When defining a list of items (i.e. not actual list comprehensions), why do you need an else statement to accompany any if statements? For example, using Python 3.7 say that we have some condition which could be true or false, and we want to include an element in a list if the condition is true, and not include it if it's false.

condition = False
lyst = ['a', 'b', 'c' if condition]

I would expect it to assign ['a', 'b'] to lyst, but it throws a syntax error. It works if we include an else statement:

lyst = ['a', 'b', 'c' if condition else 'd']

But now the result is that lyst = ['a', 'b', 'd'] In this question, user Plankton's answer further specifies that you can't use a "pass" in the else statement. My question is why the else statement is required? Is it so that the list that gets created is guaranteed to have the number of items expected? If so, this strikes me as not very pythonic.

This is particularly weird because you can have if statements without else statements in actual list comprehensions e.g.:

post = [x for x in range(10) if x > 5]
# equivalent to: post = [6, 7, 8, 9]

I realize a list comprehension is totally different functionality. Please remember that my question is why you can't use an if statement without an else in a list literal? Does this limitation avoid some issue I'm not aware of?

Alex
  • 2,154
  • 3
  • 26
  • 49
  • 6
    `['a', 'b', 'c']` notation is not a list comprehension. – user2357112 Aug 17 '18 at 18:05
  • 3
    `x if cond else y` in Python is an expression. It must have a value regardless of whether the condition is true or false. That's why you always must provide an alternative. You confuse the expression with the `if cond: do_somethig` statement. – DYZ Aug 17 '18 at 18:05
  • [Conditional Expressions](https://docs.python.org/2.5/whatsnew/pep-308.html) – Ben Jones Aug 17 '18 at 18:08
  • 1
    `if condition else 'd'` is a conditional expression. In some ways it's _similar_ to the `if` expression permitted in a comprehension, but it's not the same. And both of those are different to an `if... elif... else` compound statement. – PM 2Ring Aug 17 '18 at 18:08
  • 1
    This is a *very* general question, leading into the tutorial level (off-topic). Each of the techniques you've mentioned works differently, as you're finding. When to use each depends entirely on what you're trying to do at the time. – Prune Aug 17 '18 at 18:09
  • @user2357112 good point, I had this worded correctly in the actual question, but not in the title. Fixing now... – Alex Aug 17 '18 at 18:10
  • It would be nice if Python 3 still had a nice simple term for "list displays that aren't comprehensions" (besides the hopelessly technical `starred_list` from the grammar). – abarnert Aug 17 '18 at 18:15
  • FWIW, you _could_ do `lyst = ['a', 'b'] + (['c'] if condition else [])` – PM 2Ring Aug 17 '18 at 18:31

7 Answers7

4

You are confusing the conditional expression a if b else c with the syntax for a list comprehension, which requires a for ... in ... clause that can have an optional if (but no else).

  1. The expression

    ['a', 'b', 'c' if condition]
    

    is a syntax error, because it's not a list comprehension (no for), and c if condition is not a valid expression (no else).

  2. The expression

    ['a', 'b', 'c' if condition else 'd']
    

    is a valid list literal, consisting of the values 'a', 'b', and 'c' if condition else 'd' (which evaluates to either 'c' or 'd' depending on the value of condition).

  3. The expression

    [x for x in range(10) if x > 5]
    

    is a list comprehension, with if x > 5 being a filter applied to the value of x each time you take a value from range(10).

chepner
  • 497,756
  • 71
  • 530
  • 681
1

This has nothing to do with list-comprehensions. It's purely about lists, and how to create one using list-literals.

And a list literal is comprised of an opening bracket, and a list of expressions separated by commas.

So in your case, your 'a' and 'b' are expressions (string literals). However 'c' if condition' is not an expression. It's a half-backed if-STATEMENT (much different beast)!

But as ternary operators (x if c else y) are expressions, you can use them.

deets
  • 6,285
  • 29
  • 28
0

['a', 'b', 'c' if condition else 'd'] is interpreted as ['a', 'b', ('c' if condition else 'd')]. It's not a list comprehension, you're just creating a literal list.

BallpointBen
  • 9,406
  • 1
  • 32
  • 62
0

As posted in the comments, your snippet is not list comprehension. You are creating a list with one of the elements as an expression.

condition = False
list = ['a', 'b', 'c' if condition else None]

With you example of list = ['a', 'b', 'c' if condition] (which will fail) you might as well do any of the following:

Add c conditionally

condition = False
list = ['a', 'b']
if condition:
    list.append('c')

Use list comprehension to remove None values

condition = False
list = ['a', 'b', 'c' if condition else None]
final_list = [i for i in list if i is not None]
Jim Wright
  • 5,905
  • 1
  • 15
  • 34
0

There are two seperate language features here: ternaries (conditional expressions) and filtering.

Ternary:

x = 1 if 5 == 5 else 2
#1

Filtering:

l = [1,2,3,4,5]
l = [i for i in l if i < 3]
#[1,2,3]

These are the only two syntactical features you are using, just that you are confusing yourself by using a ternary inside a list definition:

l = [1,2,3 if 5 == 5 else 4]

see how this is equivalent to:

x = 3 if 5 == 5 else 4
l = [1,2,x]
Joe Iddon
  • 20,101
  • 7
  • 33
  • 54
0

It's not a list comprehension. It's a list with 3 values. The problem is, your 3rd value is 'c' if condition. That's not a valid value in python. It has nothing to do with lists. You could not write x = 'c' if condition either. On the other hand, the ternary if-else which you are using on the second example is a valid value, and that's why it gets accepted.

blue_note
  • 27,712
  • 9
  • 72
  • 90
-2

I believe if you want your list to be ['a', 'b', 'c'] or `['a', 'b'] then you put the if statement outside as follows:

mylist = ['a', 'b', 'c' if condition else None]

This isn't a list comprehension (above): in list comprehensions there is some loop and a single if that acts as a filter. Your code is a conditional (ternary) expression which must be evaluated to produce a result.

N Chauhan
  • 3,407
  • 2
  • 7
  • 21