 Recnac

# Python Tricks - Basic - Part 1

• Feb 26, 2020
• 7,677 Views
• Feb 26, 2020
• 7,677 Views
Data
Python

## 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:

1. A brief description of the concept and an interactive code example
2. 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)`.
``````1a, b = 0, 42
2a or b
3# output: 42
4
5a, b = '', 0
6a or b
7# output: 0``````
python

#### Inspiring Example

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

### a and b

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

#### Inspiring Example

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

### 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

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

## Value of Boolean

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

#### Inspiring Examples

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

## 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:

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

#### 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.

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

### Boolean Expression Technique

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,))
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.

### Boolean Index Technique

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.

### 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.

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

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.

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

#### Inspiring Example

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

### Chained Comparison

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

#### Inspiring Examples

``````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)):
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):
15                process_neighbor_logic(matrix[I][J])``````
python

## 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.