If and Comparisons
The if-statement uses comparisons like
i < 6 to control if lines run or not.
The if-statement controls if some lines run or not. A "boolean" is a value which is True or False. The if-statement has a boolean-test, a colon, and indented lines of code (similar to "while"):
if boolean-test: indented body lines
The if-statement first evaluates the the boolean test, and if it is True, runs the "body" lines once. Otherwise if the test is False, the body lines are skipped and the run continues after the last body line.
The simplest and most common sort of boolean test uses
== (two equal signs next to each other) to compare two values, yielding True if the two are the same.
Here is an example that shows an if-statement inside a for-loop. Every time through the loop, the test
num == 6 is evaluated, yielding boolean True or False each time.
>>> for num in [2, 4, 6, 8]: if num == 6: print('Here comes 6!') print(num) 2 4 Here comes 6! 6 8
If test = vs. == Syntax Error
It's very easy to accidentally type a single equal sign for a comparison like the following, but in Python that is flagged as a syntax error:
if num = 6: # typo, meant == print('hi')
Style: Do Not Write x == True
Suppose some foo() function is supposed to return True or False. Do not write an if-test like this:
if foo() == True: # NO, do not use == True print('yay')
Instead, let the if/while take the boolean value directly like this:
if foo(): # YES this way print('yay') # Or to test if foo() is False use not: if not foo(): print('yay is cancelled')
else: part of an if-statement adds code to run in the case that the test is False. Use
else: if the run should choose between either action-1 or action-2 depending on the test, but not do nothing. Use regular if to do action-1 or nothing.
# set message according to score if score > high_score: message = 'New high score!' else: message = 'Oh well!
To run code if a test is False and otherwise do nothing, use
not like this:
if not foo(): message = 'no foo today'
Boolean Comparison Operators
The most common way to get a boolean True/False is comparing two values, e.g. the comparison expression
num == 6 evaluates to True when num is 6 and False otherwise.
== test if two values are equal (2 equals signs together). Works for int, string, list, dict, .. most types. Not recommended to use with float values.
!= not-equal, the opposite of equal (uses == under the hood)
< <= less-than, less-or-equal. These work for most types that have an ordering: numbers, strings, dates. For strings,
< provides alphabetic ordering. Uppercase letters are ordered before lowercase. It is generally an error to compare different types for less-than, e.g. this is an error:
4 < 'hello'
> >= greater than, greater-or-equal.
The interpreter examples below shows various
== style comparisons and their boolean results:
>>> 5 == 6 False >>> 5 == 5 True >>> 5 != 6 True >>> 4 > 2 True >>> 4 > 5 False >>> 4 > 4 False >>> 4 >= 4 # contrast >= vs. > True >>> s = 'he' + 'llo' >>> s == 'hello' True >>> 'apple' < 'banana' True >>> 'apple' < 4 TypeError: '<' not supported between instances of 'str' and 'int'
There is a more rarely used
elif for where a series of if-tests can be strung together (mnemonic: 'elif' is length 4, like 'else'):
if s == 'a': # a case elif s == 'b': # b case else: # catch-all case
The tests are run top to bottom, running the code for the first that is True. However, the logic of when each case runs can be hard to see. What must be true for case c below? You really have to think about the code work work out when (c) happens.
if score > high and s != 'alice': # a elif s == 'bob': # b else: # c
Answer: c happens when s is not 'bob' but also (score <= high or s == 'alice or both)
If/else chains are fine, just don't think they are trivial. Only add
else if the code needs it. Nice, simple if handles most problems and is the most readable.
Return vs. if/else chains
Nick style idea: only use
else when it is truly needed. If the code can work using only a plain-if, I prefer to write it that way. This works extra well with decomposed out functions, where 'return' can be used to bail out for the first few cases, leaving the main case below without indentation, like this:
def foo(s): if len(s) < 4: return 'too small!' if len(s) > 100: return 'too big!' # rest of computation having screened out too-short and too-long # notice: no if-else structure, not indented down here ...
You can use else if you prefer, just thinking about possible alternative structure here.
Python if - de-facto True/False
The Python if statement looks like this
if test: print('test is true!')
Surprisingly, any value can be used in the test expression - string, int, float, list, ...
Python has a de-facto True/False system, where all the "empty" values count as de-facto False: '', None, 0, 0.0, empty-list, empty-dict
Any other value de-facto counts as True: a non-empty string, a non-zero int, a non-empty list. Many languages use this
anything-empty-is-false system. The
bool() function takes
any value and returns a formal bool False/True value, so that's a way to see the empty=False interpretation:
>>> bool(0) False >>> bool(0.0) False >>> bool('') # empty string - False False >>> bool() # empty list - False False >>> bool(None) False >>> bool(6) # non-zero int - True True >>> bool('hi') # non-empty string - True True >>> bool([1, 2]) # list of something - True True
Why does the de-facto system exist? It makes it easy to test, for example, for an empty string like the following. Testing for "empty" data is such a common case, it's nice to have a shorthand for it.
# long form screen out empty string if len(s) > 0: print(s) # shorter way, handy! if s: print(s)
Copyright 2020 Nick Parlante