Using "and" and "or" operator with Python strings
Asked Answered
A

6

30

I don't understand the meaning of the Python code line:

parameter and (" " + parameter) or ""

which is using strings along with logical operators and and or. Also the type of the variable parameter is a string.

In this context, as I can't imagine a case where usage of boolean operators on strings would make sense, I want to ask the question:

Why would one want to use logical and and or operators with python strings in general and especially which sense does it make in the case of the above expression?

The answers on stackoverflow to the question How do "and" and "or" act with non-boolean values? and the up to now given answers explain what the above line of code does, but are still missing to address the question "Why would one want to use logical and and or operators with python strings in general and especially which sense does it make in the case of the above expression (compared to another possible options for writing code to achieve the same effect)?

The above question addresses the specific case of logical and and or operators applied to strings which wasn't addressed yet by another questions present on stackoverflow, so isn't a duplicate one.

Agora answered 6/10, 2013 at 20:22 Comment(2)
It's " " + parameter if parameter else "" with extra obscurity.Fennel
@Smac89: It does make sense, but some people will consider this unpythonic.Saturninasaturnine
F
34

Suppose you are using the value of parameter, but if the value is say None, then you would rather like to have an empty string "" instead of None. What would you do in general?

if parameter:
    # use parameter (well your expression using `" " + parameter` in this case
else:
    # use ""

This is what that expression is doing. First you should understand what and and or operator does:

  • a and b returns b if a is True, else returns a.
  • a or b returns a if a is True, else returns b.

So, your expression:

parameter and (" " + parameter) or ""

which is effectively equivalent to:

(parameter and (" " + parameter)) or  ""
#    A1               A2               B
#           A                     or   B

How the expression is evaluated if:

  • parameter - A1 is evaluated to True:

    result = (True and " " + parameter) or ""
    
    result = (" " + parameter) or ""
    
    result = " " + parameter
    
  • parameter - A1 is None:

    result = (None and " " + parameter) or ""
    
    result = None or ""
    
    result = ""
    

As a general suggestion, it's better and more readable to use A if C else B form expression for conditional expression. So, you should better use:

" " + parameter if parameter else ""

instead of the given expression. See PEP 308 - Conditional Expression for motivation behind the if-else expression.

Forestall answered 6/10, 2013 at 20:27 Comment(1)
Note however, if parameter is an expression which has a string value but also has some side-effect then 'parameter and ""' and 'parameter if parameter else ""' can cause different behavior as in the first case parameter is evaluated once while in the second (the if...else syntax) parameter will be evaluated twiceOffshore
N
8

Python considers empty strings as having boolean value of "false" and non-empty strings as having boolean value of "true".

So there're only two possible outcomes of the expression, i.e. for empty string and for non-empty string.

Second thing to notice is that which value of "or" and "and" operator are returned. Python does not return just true or false value, for strings and or/and operator it returns one of the strings (considering they have value of true or false). Python uses lazy approach:

For "and" operator if left value is true, then right value is checked and returned. if left value is false, then it is returned

For "or" operator if first value is true, then it is returned. otherwise if second value is false, then second value is returned

parameter = 'test'
print( parameter and (" " + parameter) or "" )

ouput: test

parameter = ''
print( parameter and (" " + parameter) or "" )

output:(empty string)

Navarra answered 6/10, 2013 at 20:38 Comment(0)
D
5

Empty string in Python is equivalent of a False boolean value, the same way as an empty list. The line you've presented is Python version of a ternary operator (as noted in the comment below, nowadays an obsolete construction, as Python now has a real ternary operator). It is based on three rules:

  • a and b: if a is False then b won't be evaluated
  • a or b: if a is True then b won't be evaluated
  • the value of a logical clause is the value of its most recently evaluated expression

If parameter evaluates to True the second part of the and clause will get evaluated: (" " + parameter). So it will add leading space to a parameter if it's not an empty string. The second part of the or clause won't get evaluated, as you can already tell the whole expression is True (True or "anything" is always True).

If parameter is False (empty string in this context) the second part of the and clause won't get evaluated, and as you can already tell it's False (False and anything is always False). Therefore the second part of the or clause gets evaluated returning an empty string.

You can write it in a more verbose way:

if parameter:
    return " " + parameter
else:
    return ""
Disinterest answered 6/10, 2013 at 20:27 Comment(0)
C
2

It checks if parameter has a value. If it does it prepends a space. If not it returns an empty string.

$ python
Python 2.7.2 (default, Oct 11 2012, 20:14:37) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> foo = 'bar'
>>> foo and (" " + foo) or ""
' bar'
Camber answered 6/10, 2013 at 20:25 Comment(1)
Correct, but you might want to explain how this works.Saturninasaturnine
Q
2

Consider this TTL. Then it's just plugging in different scenarios to see what happens :)

Note that and and or evaluate to the first value that made them "succeed" or "fail" - and this need not be True or False!

a    b    a or b   a and b
--   --   ------   ------- 
T    T    a (T)    b (T)
T    F    a (T)    b (F)
F    T    b (T)    a (F)
F    F    b (F)    a (F)

T and F represent "Truth-y" and "False-y" values. This expression-chaining works because the operators need not return True or False - it will be either the value of a or b.

Quenchless answered 6/10, 2013 at 20:36 Comment(0)
M
1

With all the good answers, I found these statements help me remember this better and fit how my brain works (and hopefully for for some more out there) :

  • “and" returns the first False item (e.g., None, “”, [], (), {}, 0) or the last item if none (e.g. no False found)

  • “or" returns the first True item or the last item (e.g. no True found)

In summary they all return the first item that decides the outcome of the statement. (In the worst case, the last item in the sequence)

Note this rule also applies to a chained all "and" or all "or" statement

Maceio answered 1/8, 2017 at 23:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.