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

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)`

.

```
1a, b = 0, 42
2a or b
3# output: 42
4
5a, b = '', 0
6a or b
7# output: 0
```

python

In a linked list assignment, if at most one of the two candidate nodes is not `None`

, we can use `or`

expression.

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

python

If `a`

is the falsy value, return `a`

. Otherwise, return `b`

.

```
1a, b = 1, 2
2a and b
3# output: 2
4
5a, b = '', 'abc'
6a and b
7# output: ''
```

python

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

.

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

python

*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 guide.

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

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

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

python

`bool`

type is a subclass of `int`

. As an integer, the value of `True`

is 1 and `False`

is 0.

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

python

We can use `bool`

to participate in operations.

Used in `sum`

: count the number of satisfied conditions.

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

python

Used as an index: construct a temporary tuple and use `bool`

expression as an index.

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

python

Used in list initialization and slice:

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

python

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.

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

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

python

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

/`max`

function.

```
1"""find maximum in pairs"""
2a, b = 10, 20
3max_val = a if a > b else b
4# output: 20
5
6"""find mininmum in triplets"""
7a, b, c = 10, 20, 5
8min_val = a if a < b and a < c else (b if b < c else c)
9# output: 5
```

python

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

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

python

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

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

```
1"""tuple index"""
2"""for safety we explicitly test for truthiness by bool()"""
3(false_expression, true_expression)[bool(condition)]
4
5"""dict index"""
6{True: true_expression, False: false_expression}[bool(condition)]
7
8"""lambda version supports lazy evaluation"""
9(lambda: false_expression, lambda: true_expression)[bool(condition)]()
```

python

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.

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.

```
1"""pack as function"""
2"""not not x equals to bool(x)"""
3def _if(condition):
4 return lambda false_expression: lambda true_expression: \
5 [delay(true_expression), delay(false_expression)][not not condition]()
6
7"""unified as callable"""
8def delay(f):
9 if callable(f): return f
10 else: return lambda: f
11
12# example
13a, b = 10, 20
14min_val = _if(a < b) (a) (b)
15# output: 10
```

python

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

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.

`1x = y = f()`

python

is equivalent to

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

python

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

```
1import random
2x = y = random.random()
3x == y
4# output: True
5
6x = random.random()
7y = random.random()
8x == y
9# output: False
```

python

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

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

python

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

```
1a = b = 1
2
3a == b == 1
4# output: True
5
6a == b != 2
7# output: True
8
90 <= a < 4
10# output True
```

python

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

python

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:

I hope you enjoyed it. If you have any questions, you're welcome to contact me at [email protected]