115

Is it possible to do this on one line in Python?

if <condition>:
    myList.append('myString')

I have tried the ternary operator:

myList.append('myString' if <condition>)

but my IDE (MyEclipse) didn't like it, without an else.

JCB
  • 1,797
  • 5
  • 18
  • 22

8 Answers8

160

Yes, you can do this:

<condition> and myList.append('myString')

If <condition> is false, then short-circuiting will kick in and the right-hand side won't be evaluated. If <condition> is true, then the right-hand side will be evaluated and the element will be appended.

I'll just point out that doing the above is quite non-pythonic, and it would probably be best to write this, regardless:

if <condition>: myList.append('myString')

Demonstration:

>>> myList = []
>>> False and myList.append('myString')
False
>>> myList
[]
>>> True and myList.append('myString')
>>> myList
['myString']
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • 22
    While this answer is technically correct, it's not a good programming practice. Since Python aims to be a language that's easily readable, this code would be considered non-Pythonic. – Mr. Lance E Sloan Oct 15 '13 at 09:44
  • 12
    @LS: I agree, that's why I said it would probably be best to just use an if statement. But I modified the answer a bit to make that clearer. – Claudiu Oct 15 '13 at 15:54
  • 5
    fyi the second example will fail pep8 checks: `E701 multiple statements on one line` so also non-pythonic... ;) – Cas Feb 18 '17 at 17:59
  • 1
    Note that this and-shortcircuiting doesn't seem to work for assignments: ` and (strng = 'myString')` – oulenz Mar 24 '18 at 10:45
  • This is not foolproof if you have `objects/dictionaries` in the condition: `x = object['attribute'] or None` will throw a `KeyError` exception if there is no `attribute` key in object. The correct way will still be: `x = object['attribute'] if 'attribute' in object else None` – Ulysses Sep 04 '18 at 08:10
  • 2
    @hard_working_ant The "correct" way would be `x = object.get('attribute')` in that case – wihlke Apr 06 '20 at 16:44
  • 1
    @wihlke : yes and further adding x = object.get('attribute', None) to default to None – Ulysses Apr 20 '20 at 17:12
  • 2
    @overflower dict.get already defaults to None. – wihlke Jul 20 '21 at 22:53
63

The reason the language doesn't allow you to use the syntax

variable = "something" if a_condition

without else is that, in the case where a_condition == False, variable is suddenly unknown. Maybe it could default to None, but Python requires that all variable assignments actually result in explicit assignments. This also applies to cases such as your function call, as the value passed to the function is evaluated just as the RHS of an assignment statement would be.

Similarly, all returns must actually return, even if they are conditional returns. Eg:

return variable if a_condition

is not allowed, but

return variable if a_condition else None

is allowed, since the second example is guaranteed to explicitly return something.

Emmett Butler
  • 5,969
  • 2
  • 29
  • 47
  • 1
    But I wanted to use it like this: `continue if i == 0` in a for loop. – karantan Sep 29 '15 at 12:53
  • 2
    Are you allowed to do `else pass?` – AAM111 Jan 11 '17 at 00:51
  • 5
    `else pass` doesn't work because the ternary expression should return a value that can be passed to `return`. `pass` is not a valid `return` value. – Emmett Butler Feb 09 '17 at 23:25
  • 5
    I don't agree that this motivation is the real reason, given that `if a_condition: variable = "something"` and `if a_condition: return variable` are legal. So it is essentially an arbitrary syntactic choice of python. – oulenz Mar 24 '18 at 10:40
  • What if I want to append something to a list if the condition is True? Like: `mylist.append("hi") if append_smth == True` – Yılmaz Alpaslan Jan 23 '22 at 09:39
15
if <condition>: myList.append('myString')

Otherwise, no. Why the need to put it on one line?

Note that the "ternary operator" is an operator. Like any operator, it must return something, so how can you have a ternary operator without the else clause? What is it supposed to return if the condition isn't true-like?

mgilson
  • 300,191
  • 65
  • 633
  • 696
12

You are basically asking for do_thing() if <condition> else pass construct (which will throw SyntaxError, if ran). As I have discovered during research for (somewhat) similar question do_thing() if condition else None is as close as you can get (which is just another way to do <condition> and do_thing()). So, to summarize this idea and other answers, here are your options:

  • if <condition>: myList.append('myString') — seems to be the least 'hacky' (and thus preferred) way
  • <condition> and myList.append('myString')
  • myList.append('myString') if <condition> else None
  • The least hacky way doesn't work. At least not on the REPL - one gets a syntax error. Seems like it's caused by preceding code on the same line. This needs to be executed on its own line instead. But even then user input is required to skip the ellipsis. – Unknow0059 Aug 06 '20 at 18:00
3

myList.extend(['myString'] if condition else []) would also work, though it's more work than the other solutions.

Jake Biesinger
  • 5,538
  • 2
  • 23
  • 25
3

i’d just do this if i wanna add optional elements to a list based on a condition.

nums = [
        1,
        2,
        3 if <condition> else None,
        4,
       ]

# nums now contains values of `None`, so we delete all occurrences of `None`
nums.remove(None)

this just replaces the value with None if the condition is not met and then later, it just redefines the list without the None Values. this way they preserve their index if the condition is met

TheClockTwister
  • 819
  • 8
  • 21
poison_pwn
  • 76
  • 2
  • 6
1

You can do something like below. Note that None is never at any point appended to myList.

myList.append('myString') if <condition> else None

Also, Python should accept the one-liner below.

if <condition>: myList.append('myString')
  • False and 0 are not appended to the list. The line just needs to return something if the condition is not met. You can replace the 0 or False with None or an empty string, or anything you want, and it will not affect the list. – Zachary Chiodini Jun 15 '20 at 22:03
  • I think my thought at the time was in the case of a list comprehension. Deleted my comment, downvote wasn't me. I suppose a cleaner way would be to do `myList.append('myString') if True else _` But if you're not assigning to anything, doesn't matter. I'm concerned about this person attempting a list-comprehension with similar logic though. – Dave Liu Jun 18 '20 at 19:45
0
def map_key_vs_values(db, key_name, val_name):
    _map = {}
    for item in db:
        p = item[key_name]
        a = item[val_name]

        try: a not in _map[p] and _map[p].append(a)
        except: _map[p] = [a]
        
    return _map
  • This answer was reviewed in the [Low Quality Queue](https://stackoverflow.com/help/review-low-quality). Here are some guidelines for [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer). Code only answers are **not considered good answers**, and are likely to be downvoted and/or deleted because they are **less useful** to a community of learners. It's only obvious to you. Explain what it does, and how it's different / **better** than existing answers. [From Review](https://stackoverflow.com/review/low-quality-posts/32470855) – Trenton McKinney Aug 13 '22 at 17:45