if/else in a list comprehension
Tags: python
Published: 2023-10-29 13:57:28

Let's use this question to review some concepts. I think it's good to first see the fundamentals so you can extrapolate to different cases.

Other answers provide the specific answer to your question. I'll first give some general context and then I'll answer the question.

Fundamentals
============

`if/else` statements in list comprehensions involve two things: 

 - List comprehensions
 - Conditional expressions (Ternary operators)

## 1. List comprehensions

They [provide][1] a concise way to create lists.

Its structure consists of: "*brackets containing an expression followed by a for clause, then zero or more for or if clauses*".

### Case 1

Here we have no condition. Each item from the iterable is added to `new_list`.

```python
    new_list = [expression for item in iterable]
    new_list = [x for x in range(1, 10)]
    > [1, 2, 3, 4, 5, 6, 7, 8, 9]
```

### Case 2

Here we have one condition.

**Example 1**

Condition: only *even* numbers will be added to `new_list`.

```python
    new_list = [expression for item in iterable if condition == True]
    new_list = [x for x in range(1, 10) if x % 2 == 0]
    > [2, 4, 6, 8]
```

**Example 2**

Condition: only *even* numbers that are multiple of 3 will be added to `new_list`.

```python
    new_list = [expression for item in iterable if condition == True]
    new_list = [x for x in range(1, 10) if x % 2 == 0 if x % 3 == 0]
    > [6]
```

But howcome we have one condition if we use two `if` in `new_list`?

The prior expression could be written as:

```python
    new_list = [x for x in range(1, 10) if x % 2 and x % 3 == 0]
    > [6]
```

We only use one `if` statement.

This is like doing:

```python
    new_list = []
    for x in range(1, 10):
        if x % 2 == 0 and x % 3 == 0:
            new_list.append(x)
    > [6]
```

**Example 3**

Just for the sake of argument, you can also use `or`.

Condition: *even* numbers or numbers multiple of 3 will be added to `new_list`.

```python
    new_list = [x for x in range(1, 10) if x % 2 == 0 or x % 3 == 0]
    > [2, 3, 4, 6, 8, 9]
```

### Case 3

More than one condition: 

Here we need the help of conditional expressions (Ternary operators).


## 2.Conditional Expressions

What are conditional expressions? What the name says: a Python expression that has some condition.

```python
    <Exp1> if condition else <Exp2>
```

First the `condition` is evaluated. If `condition` is `True`, then `<Exp1>` is evaluated and returned. If `condition` is `False`, then `<Exp2>` is evaluated and returned.


A conditional expression with more than one condition:

```python
    <Exp1> if condition else <Exp2> if condition else <Exp3>...    
```

An example from [Real Python][2]:

```python
    age = 12
    s = 'minor' if age < 21 else 'adult'
    > minor
```

The value of `s` is conditioned to `age` value.


## 3.List Comprehensions with Conditionals

We put list comprehensions and conditionals together like this.

```python
    new_list = [<Conditional Expression> for <item> in <iterable>]

    new_list = [<Exp1> if condition else <Exp2> if condition else <Exp3> for <item> in <iterable>]
```

Condition: *even* numbers will be added as `'even'`, the number three will be added as `'number three'` and the rest will be added as `'odd'`.

```python
    new_list = ['even' if x % 2 == 0 else 'number three' if x == 3 else 'odd' 
                 for x in range(1, 10)]
    > ['odd', 'even', 'number three', 'even', 'odd', 'even', 'odd', 'even', 'odd']
```
----------

# The answer to the question

```python
    [f(x) for x in xs if x is not None else '']
```

Here we have a problem with the structure of the list: `for x in xs` should be at the end of the expression.

Correct way:

```python
    [f(x) if x is not None else '' for x in xs]
```


NOTE: Originally posted in StackOverflow
https://stackoverflow.com/a/68969401/6710903

----------
Further reading:

[Does Python have a ternary conditional operator?][3]


  [1]: https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions
  [2]: https://realpython.com/python-conditional-statements/
  [3]: https://stackoverflow.com/questions/394809/does-python-have-a-ternary-conditional-operator