2

Is there any Pythonic or compact way to write the following if statement:

if head is None and tail is None:
    print("Test")

Something like:

if (head and tail) is None: 
5
  • Nope, that's how you write it. Martijn's suggestion will suffice if there are no valid but false-y values (e.g. ''). Commented Dec 2, 2016 at 13:41
  • If there's no chance of the values being falsey for some other reason: if not head and not tail: Commented Dec 2, 2016 at 13:42
  • 1
    Can head or tail possibly take on any other false-ish value? Commented Dec 2, 2016 at 13:42
  • @PM2Ring: oops, indeed. Commented Dec 2, 2016 at 13:44
  • Note that and short-circuits, so the 2nd test will not be performed if the 1st one fails, i.e., if head isn't None. So your code is already quite efficient. Commented Dec 2, 2016 at 13:46

4 Answers 4

4

If both head and tail are custom class instances (like Node() or similar) without a length or boolean value, then just use:

if not (head or tail):

This won't work if ether head or tail could be objects other than None with a false-y value (False, numeric 0, empty containers, etc.).

Otherwise, you are stuck with the explicit tests. There is no "English grammar" shortcut in boolean logic.

Sign up to request clarification or add additional context in comments.

3 Comments

Note, it will check value is not truthy (not just for None value)
if not (head or tail) (or if not head and not tail)
@KirillBulygin: I need more caffeine today.
2
if head is None and tail is None:
    print("Test")

is clear and efficient. And if either head or tail can possibly take false-ish values apart from None but you only want "Test" to be printed when they're both None then what you've written is safer than

if not (head or tail):        
    print("Test")

A more compact version (than your code) which is still both safe & efficient is

if head is None is tail:
    print("Test")

head is None is tail is actually equivalent to (head is None) and (None is tail). But I think it's a little less readable than your original version.

BTW, (head and tail) is None is valid Python syntax, but it's not recommended, since it doesn't do what you might at first expect it do:

from itertools import product

print('head, tail, head and tail, result')
for head, tail in product((None, 0, 1), repeat=2):
    a = head and tail
    print('{!s:>4} {!s:>4} {!s:>4} {!s:>5}'.format(head, tail, a, a is None))

output

head, tail, head and tail, result
None None None  True
None    0 None  True
None    1 None  True
   0 None    0 False
   0    0    0 False
   0    1    0 False
   1 None None  True
   1    0    0 False
   1    1    1 False

Comments

2

Your code is just about as Pythonic as it can be.

When it comes to these things, The Zen of Python is helpful in remembering that sometimes straightforward is the best option.

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
etc...

Comments

0

By the way, descriptions like (head and tail) is None are not allowed in programming for the same reason why (a and b) = 0 is not allowed in mathematics (to force each statement to have only one, canonical form; "There should be one obvious way to do each thing" is also an explicit Python motto).

2 Comments

What do you mean? (head and tail) is None is perfectly valid in Python, but it doesn't do what one might expect it to do. :)
I certainly mean (head and tail) is None written with the same intent as (a and b) = 0.

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.