Introduction

Python is known for its clean and expressive syntax. During my experience with Python, I discovered several Pythonic techniques to simplify for loops and if-else statements. This post explores these techniques and demonstrates how they can make your code more concise and readable.

Simplifying For Loops

For Loop

List Comprehension/Generator

A common use case is transforming a list of items into another. Here’s the traditional approach:

result = []
for item in item_list:
    new_item = do_something(item)
    result.append(new_item)

Using Python’s list comprehension, this can be simplified to:

result = [do_something(item) for item in item_list]

Using Functions

To transform a list using a function, Python provides the map function:

result = map(do_something, item_list)

For example:

squared = map(lambda x: x**2, range(10))

Extracting Functions or Generators

For more complex transformations, you can extract the logic into a function:

results = []
for item in item_list:
    # setup

    # condition

    # processing

    # calculation
    results.append(result)

Obviously you are overloading a code block.

Instead, you can do:

results = []
def process(item)
    # setup
    # condition
    # processing
    # calculation
    return result

results = [process(item) for item in item_list]

How about nested for loop?

results = []
for item in item_list:
    for sub_item in sub_item_list:
        # setup

        # condition

        # processing

        # calculation
        results.append(result)

To switch it to a list comprehension, you can do:

results = [process(item, sub_item)
           for item in item_list
           for sub_item in sub_item_list]

If you want to record some inner state of the list

a = [2,8,5,6,4,3,9,7,1]
results = []
current = 0

for i in a:
    current = max(current, i)
    results.append(current)

print(results)

# [2, 8, 8, 8, 8, 8, 9, 9, 9]

We can use generator to do the same thing

def max_generator(a):
    current = 0
    for i in a:
        current = max(current, i)
        yield current

results = list(max_generator([2, 8, 5, 6, 4, 3, 9, 7, 1]))
print(results)
# [2, 8, 8, 8, 8, 8, 9, 9, 9]

Alternatively, use itertools.accumulate for a more concise solution:

import itertools
results = list(itertools.accumulate([2, 8, 5, 6, 4, 3, 9, 7, 1], max))
print(results)
# [2, 8, 8, 8, 8, 8, 9, 9, 9]

Simplifying If-Else Statements

Ternary Operator

A simple if-else statement:

if condition:
    x = true_value
else:
    x = false_value

Can be rewritten as:

x = true_value if condition else false_value

Probability Space

Another approach is using a list indexed by the condition:

x = [false_value, true_value][condition]

Conclusion

By leveraging Python’s list comprehensions, map, generators, and ternary operators, you can write cleaner and more Pythonic code. These techniques not only reduce boilerplate but also improve readability.

I hope you find this post helpful. If you have any questions, feel free to reach out via email or GitHub.