1

Python has the Truth Value Testing feature for all the objects. Which enables the Boolean Operators a more generic definition that suits for all objects:

  • x or y: if x is false, then y, else x
  • x and y: if x is false, then x, else y

I've seen practical use cases for the OR-operator, for example:

ENV_VAR = os.environ.get(‘ENV_VAR’) or <default_value>

However, not have I seen any practical example of using the Python AND operator. Here I'm looking for examples of AND operator that takes advantage of the truth value testing like the OR operator example above.

dawranliou
  • 141
  • 2
  • 8
  • 1
    `os.getenv('ENV_VAR', default=default_value)` is better – wim Feb 26 '16 at 16:40
  • Sounds more like JavaScript... Not sure anyone uses it in Python. – IanS Feb 26 '16 at 16:49
  • You have not seen `if condition1 and condition2: do_something`? – gil Feb 26 '16 at 16:49
  • Thanks @wim, yes it does look more explicit than mine. I have another example in mind, which is `name = input('Enter your name: ') or 'Unknown'`. Do you think this is a better example here? – dawranliou Feb 26 '16 at 16:55
  • @gill, yes yours is a absolutely right example. However, I failed to see its correlation to taking advantage of truth value testing. Could you be more specific? I should've been more specific that I'd like to see examples that won't be possible in Java. – dawranliou Feb 26 '16 at 17:02

5 Answers5

1

By far the most common use of and in python is just to check multiple conditions:

if 13 <= age <= 19 and gender == 'female':
    print "it's a teenage girl"

Use cases for and which take advantage of the arguably surprising fact that x and y returns one of the operands, rather than returning a boolean, are few and far between. There is almost always a clearer and more readable way to implement the same logic.

In older python code, you can often find the construct below, which is a buggy attempt to replicate the behaviour of C's ternary operator (cond ? : x : y).

cond and x or y

It has a flaw: if x is 0, None, '', or any kind of falsey value then y would be selected instead, so it is not quite equivalent to the C version.

Below is a "fixed" version:

(cond and [x] or [y])[0]

These kind of and/or hacks are mostly obsolete now since python introduced the conditional expression.

x if cond else y
wim
  • 338,267
  • 99
  • 616
  • 750
0

The feature used in your example

os.environ.get(‘ENV_VAR’) or <default_value>

is called short circuit evaluation. If this aspect of AND and OR is the subject of your question, you may find this Wikipedia article useful:

https://en.wikipedia.org/wiki/Short-circuit_evaluation

VPfB
  • 14,927
  • 6
  • 41
  • 75
0

I found great examples for both and and or operator in this answer: https://stackoverflow.com/a/28321263/5050657

Direct quote from the answer:

Python's or operator returns the first Truth-y value, or the last value, and stops. This is very useful for common programming assignments that need fallback values.

Like this simple one:

print my_list or "no values"

...

The compliment by using and, which returns the first False-y value, or the last value, and stops, is used when you want a guard rather than a fallback.

Like this one:

my_list and my_list.pop()
Community
  • 1
  • 1
dawranliou
  • 141
  • 2
  • 8
0

I am sometimes using and when I need to get an attribute of an object if it's not None, otherwise get None:

>>> import re

>>> match = re.search(r'\w(\d+)', 'test123')

>>> number = match and match.group(1)

>>> number
>>> '123'

>>> match = re.search(r'\w(\d+)', 'test')

>>> number = match and match.group(1)

>>> number
warvariuc
  • 57,116
  • 41
  • 173
  • 227
-1

Any time you need a statement where two things should be true. For example:

# you want to see only odd numbers that are in both lists
list1 = [1,5,7,6,4,9,13,519231]
list2 = [55,9,3,20,18,7,519231]
oddNumsInBothLists = [element for element in set(list1) if element in set(list2) and element % 2]
# => oddNumsInBothLists = [7, 9, 519231]

Boolean operators, particularly the and, can generally be omitted at the expense of readability. The builtin function all() will return true if, and only if, all of its members are true. Similarly, the function any() will return true if any of its members are true.

shouldBeTrue = [foo() for foo in listOfFunctions]
if all(shouldBeTrue):
    print("Success")
else:
    print("Fail")

Perhaps an easier way of thinking about it is that or would be used in place of successive if-statements whereas and would be used in place of nested if-statements.

def foobar(foo, bar):
    if(foo):
        return foo
    if(bar):
        return bar
    return False

is functionally identical to:

def foobar(foo, bar):
    return foo or bar

And:

def foobar(foo, bar):
    if(foo):
        if(bar):
            return bar
    return False

is functionally identical to:

def foobar(foo, bar):
    return foo and bar

This can be demonstrated with a simple test.

class Foo:
    def __init__(self, name):
        self.name = name

test1 = Foo("foo")
test2 = Foo("bar")

print((test1 or test2).name) # => foo
print((test1 and test2).name) # => bar
print((not test1 and not test2).name) # => AttributeError for 'bool' (False)
Goodies
  • 4,439
  • 3
  • 31
  • 57
  • The examples you have given are not identical. – wim Feb 26 '16 at 17:18
  • @wim Functionally, I believe they are. – Goodies Feb 26 '16 at 17:20
  • Thanks @Goodies for your answer, I get your point. You are explaining the short-circuit evaluation of `and` and `or`. However, in your example functions, because they only returns the truth value based on `foo` and `bar`, you are omitting the fact that `and` and `or` can also return an object. That's why they aren't identical. – dawranliou Feb 26 '16 at 21:40
  • @dawran6 Thanks! I knew that, but it didn't cross my mind as I wrote this. Updated. – Goodies Feb 26 '16 at 21:47