123

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.

1
  • 4
    You mean like a ternary operator that doesn't have three parts? Isn't this a contradiction in terms? Commented Nov 3, 2020 at 22:21

9 Answers 9

173

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']
Sign up to request clarification or add additional context in comments.

8 Comments

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.
@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.
fyi the second example will fail pep8 checks: E701 multiple statements on one line so also non-pythonic... ;)
@hard_working_ant The "correct" way would be x = object.get('attribute') in that case
@wihlke : yes and further adding x = object.get('attribute', None) to default to None
|
69

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.

5 Comments

But I wanted to use it like this: continue if i == 0 in a for loop.
Are you allowed to do else pass?
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.
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.
What if I want to append something to a list if the condition is True? Like: mylist.append("hi") if append_smth == True
17
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?

Comments

13

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

1 Comment

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.
5

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

1 Comment

@TheClockTwister, replace last line with nums.remove(None)
4

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

Comments

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')

2 Comments

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.
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.
0

For all those people asking: "Why would you want to do that?", there is one case where that syntax would be extremely useful.

Take this code:

class a:
    def calla(self):
        print("a")

class b:
    def callb(self):
        print("b")

def c(*args):

    class c(a if args[0], b if args[1]):
        def __init__(self, *args):
            self.calla = getattr(self, "calla", None)
            if callable(self.calla):
                self.calla()
                
            self.callb = getattr(self, "callb", None)
            if callable(self.callb):
                self.callb()
                
    return c(args[2:])

C = c(False, False)

The code is attempting to conditionally inherit class a and/or/nor b. The getattr and callable lines check whether the method from class a or b exists, i.e. whether the classes were sucessfully inherited. The factory function is used to define the conditions for inheritance that are given to class c. And lastly, there are the conditions inside the definition of class c's inheritance.

Unfortunately this code doesn't run as there must be an else after the if... It cannot be avoided using a one line if statement either as starting with "if" is invalid syntax.

You also cannot else inherit object like this:

class c(a if args[0] else object, b if args[1] else object):

This code could throw an error of inheriting "object" twice if neither a or b need to be inherited. ("else None" and "else c" dont work either ofcourse)

Therefore the way to avoid it is by creating throwaway classes for a and b with nothing inside but this looks terrible and seems wrong...

class a:
    def calla(self):
        print("a")

class b:
    def callb(self):
        print("b")

class empty:
    pass
class empty2:
    pass

def c(*args):
    
    class c(a if args[0] else empty, b if args[1] else empty2):
        def __init__(self, *args):
            self.calla = getattr(self, "calla", None)
            if callable(self.calla):
                self.calla()
                
            self.callb = getattr(self, "callb", None)
            if callable(self.callb):
                self.callb()
                
    return c(args[2:])

C = c(False, False)

So it would be useful to have the ternary operator not require else.

Comments

-1
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

1 Comment

This answer was reviewed in the Low Quality Queue. Here are some guidelines for How do I write a good 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.