Can I optionally include one element in a list without an else statement in python?

Question:

I know you can do something like this in python:

>>> conditional = False
>>> x = [1 if conditional else 2, 3, 4]
[ 2, 3, 4 ]

but how would I do something like this?

>>> conditional = False
>>> x = [1 if conditional, 3, 4]
[ 3, 4 ]

That is, I don’t want to substitute the 1 for another number. I want to simply omit it if conditional is false.

Asked By: Caustic

||

Answers:

Use concatenation:

x = ([1] if conditional else []) + [3, 4]

In other words, generate a sublist that either has the optional element in it, or is empty.

Demo:

>>> conditional = False
>>> ([1] if conditional else []) + [3, 4]
[3, 4]
>>> conditional = True
>>> ([1] if conditional else []) + [3, 4]
[1, 3, 4]

This concept works for more elements too, of course:

x = ([1, 2, 3] if conditional else []) + [4, 5, 6]
Answered By: Martijn Pieters

You can do it with a slice

x = [1, 3, 4][not conditional:]

eg

>>> conditional = False
>>> [1, 3, 4][not conditional:]
[3, 4]
>>> conditional = True
>>> [1, 3, 4][not conditional:]
[1, 3, 4]
Answered By: John La Rooy

If you truly want to avoid the else, you could write a generator for the list items:

def gen_x(conditional):
    if conditional:
        yield 1
    for v in [3, 4]:
        yield v

Or, since Python 3.3:

def gen_x(conditional):
    if conditional:
        yield 1
    yield from [3, 4]

And then:

x = list(gen_x(conditional))
Answered By: mkrieger1

Slightly faster than https://stackoverflow.com/a/18988829/1093967 in Python 3.5+ (leveraging additional unpacking generalizations introduced by PEP-448):

>>> timeit("([1, 2, 3] if True else []) + [4, 5, 6]")
0.10665618600614835
>>> timeit("[*([1, 2, 3] if True else []), 4, 5, 6]")
0.08992647400009446
Answered By: deepyaman
[*(1 for _i in range(1) if conditional), 2, 3, 4]

Learned this trick from a coworker.

Answered By: victorx
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.