# Python Tricks - Basic - Part 1

Feb 26, 2020 • 11 Minute Read

## Introduction

*Editor's note: This guide is part of a series on useful Python tricks. Read more about the series and find links the other guides here.*

In this guide, we will learn some basic tricks in Python, including the most common advanced Python tricks. Each Python trick is explained in two steps:

- A brief description of the concept and an interactive code example
- Some inspiring examples to enlighten you

## Boolean Expressions

### a or b

If **a** is the truthy value, return **a**. Otherwise, return **b**.

Here is the *falsy values* list from the official document:

- Constants defined to be false:
**None**and**False**. - Zero of any numeric type:
**0**,**0.0**,**0j**,**Decimal(0)**,**Fraction(0, 1)**. - Empty sequences and collections:
**''**,**()**,**[]**,**{}**,**set()**,**range(0)**.

` ````
a, b = 0, 42
a or b
# output: 42
a, b = '', 0
a or b
# output: 0
```

#### Inspiring Example

In a linked list assignment, if at most one of the two candidate nodes is not **None**, we can use **or** expression.

` ````
"""connect with a non-empty linked list"""
cur.next = l1 or l2
```

### a and b

If **a** is the falsy value, return **a**. Otherwise, return **b**.

` ````
a, b = 1, 2
a and b
# output: 2
a, b = '', 'abc'
a and b
# output: ''
```

#### Inspiring Example

We can use this mechanism to call a function before assignment. Just make sure that the left expression is always **True**.

` ````
"""add current element to list before assignment"""
last = not arr.append(x) and arr[-1]
```

### Extended Knowledge: Lazy Evaluation

*Lazy evaluation* is an evaluation strategy that delays the evaluation of an expression until its value is needed.

Here we talk about the lazy evaluation mechanism applied to expression, such as **a or b**, **a and b**, **a if condition else b**. Once the statement is satisfied, the rest of the expression will be skipped. Specific to the following examples, expression **b** will *not be executed*. We can use this mechanism to do *conditional execution* in an expression. See more information in the "list comprehension with break" example of the Python Tricks - Black Magic - Part 2 guide.

We will further discuss the lazy evaluation technique applied to the **generator** in the Python Tricks - Iterable guide.

## Build Tuple

Construct a temporary tuple for a specific purpose. Trade memory for more concise code. This can be extended to build other collection types.

#### Inspiring Examples

` ````
"""build in condition"""
if elem in (elem1, elem2): # equals to: if elem == elem1 or elem == elem2
"""build result"""
return [dp[-1], -1][dp[-1] == float('inf')] # equals to if-else, but more concise
"""build 4-neighbors as range"""
for I, J in (i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1):
```

## Value of Boolean

**bool** type is a subclass of **int**. As an integer, the value of **True** is 1 and **False** is 0.

` ````
int(True), int(False)
# output: (1, 0)
```

We can use **bool** to participate in operations.

#### Inspiring Examples

Used in **sum**: count the number of satisfied conditions.

` ````
"""used in sum"""
equal_count = sum(a == b for a, b in zip(arr1, arr2))
```

Used as an index: construct a temporary tuple and use **bool** expression as an index.

` ````
# L236: find the lowest common ancestor in the binary search tree
def lowest_common_ancestor(root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
while (root.val - p.val) * (root.val - q.val) > 0:
"""used as index"""
root = (root.left, root.right)[p.val > root.val] # equals to if-else, seems more clearly this way
return root
```

Used in list initialization and slice:

` ````
# a strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down)
# L247: find all strobogrammatic numbers that are of length = n
def find_strobogrammatic(n: int) -> List[str]:
"""used in list initialization"""
# if nums is odd, the middle digit must be in '018'
nums = n % 2 * list('018') or ['']
while n > 1:
n -= 2
"""used in slice"""
# here use to deal with number can not start with '0'
nums = [a + num + b for a, b in '00 11 88 69 96'.split()[n < 2:] for num in nums]
return nums
```

## Ternary Operator

In C++ / Java, you can achieve this with the built-in grammar **condition ? true_expression : false_expression**. Python has several of its own ways to achieve this. A variety of solutions provide different ideas.

This section is summarized from Does Python have a ternary conditional operator? and Best way to do ternary conditionals in Python < 2.5 on Stack Overflow. Refer to them if you need.

### Built-in Grammar

This is the most direct way, which is supported since version 2.5. The expression syntax is:

` ````
"""conditional operator"""
true_expression if condition else false_expression
```

#### Inspiring Examples

We can use the ternary operator to find min/max element in pairs or triplets. The alternative is to use the **min**/**max** function.

` ````
"""find maximum in pairs"""
a, b = 10, 20
max_val = a if a > b else b
# output: 20
"""find mininmum in triplets"""
a, b, c = 10, 20, 5
min_val = a if a < b and a < c else (b if b < c else c)
# output: 5
```

### Boolean Expression Technique

For versions prior to 2.5, we can use the *boolean expression* trick that we discussed before:

` ````
"""correct way by encapsulation with tuples"""
"""(False,) is truthy value"""
(condition and (true_expression,) or (false_expression,))[0]
"""more concise and faster way with limit"""
"""should make sure true_expression is never falsy"""
condition and true_expression or false_expression
```

However, this method may create poor readability for some and be slower than before.

### Boolean Index Technique

This solution uses *value of boolean* and *build tuple* tricks.

` ````
"""tuple index"""
"""for safety we explicitly test for truthiness by bool()"""
(false_expression, true_expression)[bool(condition)]
"""dict index"""
{True: true_expression, False: false_expression}[bool(condition)]
"""lambda version supports lazy evaluation"""
(lambda: false_expression, lambda: true_expression)[bool(condition)]()
```

Note that the first two solutions always evaluate everything, whereas the if/else construct obeys lazy evaluation. They are not equal in the strict sense. The third one uses the **lambda** technique to solve this problem.

### Pack with Boolean Index

Here is an elegant Pythonic solution. It is packed as a function based on the *boolean index technique* solution. It looks pretty clean and easy to read for the caller.

` ````
"""pack as function"""
"""not not x equals to bool(x)"""
def _if(condition):
return lambda false_expression: lambda true_expression: \
[delay(true_expression), delay(false_expression)][not not condition]()
"""unified as callable"""
def delay(f):
if callable(f): return f
else: return lambda: f
# example
a, b = 10, 20
min_val = _if(a < b) (a) (b)
# output: 10
```

## Chained Operations

Chained operations make the code more concise and reduce the possibility of errors.

### Chained Assignment

In Python, assignment statements are not expressions and thus do not have a value. Instead, chained assignments are a series of statements with multiple targets for a single expression. The assignments are executed left-to-right.

` ``x = y = f()`

is equivalent to

` ````
temp = f()
x = temp # assign from left to right
y = temp
```

They all have the same values when assigning a mutable value.

` ````
import random
x = y = random.random()
x == y
# output: True
x = random.random()
y = random.random()
x == y
# output: False
```

#### Inspiring Example

A typical use case is for initialization, such as the initialization of a linked list.

` ````
"""initialize dummy node and assign to cur"""
dummy = ListNode(0)
cur = dummy.next = head
```

### Chained Comparison

Chained Comparison is a nice syntactic sugar in Python to simplify expressions.

` ````
a = b = 1
a == b == 1
# output: True
a == b != 2
# output: True
0 <= a < 4
# output True
```

#### Inspiring Examples

` ````
"""short for a > 0 and b >= 0"""
if a > 0 <= b:
"""chained comparison in binary search"""
if nums[lo] < target < nums[mid]:
hi = mid - 1
"""check matrix boundary in a unified way"""
for i in range(len(matrix)):
for j in range(len(matrix[0])):
# construct neighbor tuple
for I, J in (i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1):
# although add some unnecessary checks, expression is more concise
if 0 <= I < len(matrix) and 0 <= J < len(matrix[0]):
process_neighbor_logic(matrix[I][J])
```

## Conclusion

In this guide, we have learned many basic Python tricks, such as advanced boolean usages, build tuple, ternary operator, and chained operator. I hope some of them will be useful for you.

In Python Tricks - Basic - Part 2, we will continue to learn about other basic Python tricks.

You can also download an example notebook, basic.ipynb, from Github.

This guide is one of a series of Python tricks guides:

- Python Tricks - Introduction
- Python Tricks - Basic - Part 1
- Python Tricks - Basic - Part 2
- Python Tricks - Iterable - Part 1
- Python Tricks - Iterable - Part 2
- Python Tricks - Black Magic - Part 1
- Python Tricks - Black Magic - Part 2

I hope you enjoyed it. If you have any questions, you're welcome to contact me at recnac@foxmail.com.