A simple way to avoid multiple for loops in Python

Introduction

I think ** multiple for loop (nesting) ** is one of the most avoidable processes in programming. About a month ago, the article "Why do we stubbornly avoid for" was buzzed, and 2020/11/3 With more than 1000 LGTMs now, many people don't want to use for loops too much. There are several techniques in Python that can easily avoid multiple for loops, so I've summarized the ones I use most often. If you have any other, please let us know in the comments.

Why do you want to avoid multiple for loops in the first place?

I think there are various reasons for each person (also discussed in detail in the above article), but personally I have the following two points.

1. Difficult to read

As an example of multiple for loops, let's write a program that searches all 0 to 999 by turning a for statement from 0 to 9 for each of the 3 digits, and searches for numbers that are 500 or more and doublet. (suitable) Even just a triple for loop will make you sick.

bad example



result = []
for i in range(10):
    for j in range(10):
        for k in range(10):
            summed = i*100+j*10+k
            if i == j == k and summed >= 500:
                result.append(summed)
print(result)

#Execution result-> [555, 666, 777, 888, 999]

It's still good because the process is simple, but it gets really hard to read when it gets more complicated.

2. The process of exiting loops at once is very difficult to read.

Often, when you meet certain conditions, you want to get out of all the loops, not just the innermost loop. As an example, write a program that ends the process if even one doublet is found in the process of 1. above. When I search for "how to get out of python multiple loops" on Google, although there is a difference that flag is not used, it is written as follows.

There is a bad example break





result = []
for i in range(10):
    for j in range(10):
        for k in range(10):
            summed = i*100 + j*10 + k
            if i == j == k and summed >= 500:
                result.append(summed)
                break
        else:
            continue
        break
    else:
        continue
    break

print(result)

#Execution result-> [555]

This is pretty hard to read. It's very hard to tell where and where the indentation is the same. If you try to write more complex processes, you'll end up with code that no one can understand.

Method A. Use itertools

By using itertools, you can generate iterators that produce all combinations and avoid multiple for loops. Also, since iterators are generated, even if you make all the combinations, it will not consume a lot of memory. If you want to list all the combinations you have created, just enclose the iterator created by the built-in function list (). (Be careful about memory consumption when listing)

When I write the code that breaks out of the loop using itertools,

When using itertools


import itertools

all_nums_iter = itertools.product(range(10),repeat=3)

result = []
for num in all_nums_iter:
    summed = num[0]*100 + num[1]*10 + num[2]
    if num[0] == num[1] and num[1] == num[2] and summed >= 500:
        result.append(summed)
        break
print(result)

#Execution result-> [555]

I think it's easier to see. By the way, itertools has a function that can not only enumerate all, but also enumerate combinations and permutations with and without duplication.

Method B. Use numpy.npindex

If you're already using a numpy array, you can use numpy.npindex to avoid multiple for loops. numpy.npindex turns the for statement so that all the values in the received array are brute force. In the code below, options.shape is (10, 10, 10), so i, j, and k are full search for statements from 0 to 9 respectively.

numpy.When using npindex


import numpy as np

options = np.array([[[100*i+10*j+k for i in range(10)] for j in range(10)] for k in range(10)], dtype="int")

result = []
for i, j, k in np.ndindex(options.shape):
    summed = options[i,j,k]
    if i == j and j == k and summed >= 500:
        result.append(summed)
        break
    
print(result)

#Execution result-> [555]

It's pretty refreshing.

Method C. Use recursive function

It's a little difficult and I think it's used in a limited number of situations, but you can also do a full search with a recursive function. If you are not familiar with recursive functions, see "What kind of world will expand if you learn recursive functions" in the reference below. I think it's pretty easy to understand.

When using a recursive function


def dfs(depth, num):
    if depth == 3:
        num_str = str(num).zfill(3)
        return num if num_str[0] == num_str[1] == num_str[2] and num >= 500 else None
    
    for i in range(10):
        ret = dfs(depth + 1, num + 10**(2-depth) * i)
        if ret:
            return ret
        
print(dfs(0, 0))

#Execution result-> 555

You can use it in a limited number of situations, but you can write intuitive code in specific situations (DFS: depth-first search, etc.).

reference

Why do we stubbornly avoid for Method often used in atcoder python version What kind of world will expand when you learn recursive functions

At the end

Thank you for reading to the end. Let's simplify the hard-to-read multiple for loops. If you know of any other easy way to write, please let me know in the comments. If you find this article helpful, please use LGTM!

Recommended Posts

A simple way to avoid multiple for loops in Python
Avoid multiple loops in Python
How to define multiple variables in a python for statement
A clever way to time processing in Python
Searching for an efficient way to write a Dockerfile in Python with poetry
How to slice a block multiple array from a multiple array in Python
A standard way to develop and distribute packages in Python
Implementing a simple algorithm in Python 2
Introducing a good way to manage DB connections in Python
Run a simple algorithm in Python
Seeking a unified way to wait and get for state changes in Selenium for Python elements
[Introduction to Python] How to use the in operator in a for statement?
[For beginners] How to register a library created in Python in PyPI
How to delete multiple specified positions (indexes) in a Python list
Avoid nested loops in PHP and Python
A simple HTTP client implemented in Python
Try drawing a simple animation in Python
Create a simple GUI app in Python
Send email to multiple recipients in Python (Python 3)
Decorator to avoid UnicodeEncodeError in Python 3 print ()
How to get a stacktrace in python
Easy way to use Wikipedia in Python
Process multiple lists with for in Python
Write a simple greedy algorithm in Python
Get a token for conoha in python
Write a simple Vim Plugin in Python 3
A way to understand Python duck typing
[Python / Tkinter] Search for Pandas DataFrame → Create a simple search form to display
How to write a string when there are multiple lines in python
What is the fastest way to create a reverse dictionary in python?
Set up a simple HTTPS server in Python 3
The fastest way for beginners to master Python
Try to calculate a statistical problem in Python
How to clear tuples in a list (Python)
To execute a Python enumerate function in JavaScript
How to embed a variable in a python string
I want to create a window in Python
How to create a JSON file in Python
Steps to develop a web application in Python
A simple Pub / Sub program note in Python
Try to calculate RPN in Python (for beginners)
Notes for implementing simple collaborative filtering in Python
To add a module to python put in Julialang
Create a simple momentum investment model in Python
How to notify a Discord channel in Python
Set up a simple SMTP server in Python
[Python] How to draw a histogram in Matplotlib
Tips for using ElasticSearch in a good way
[Cloudian # 10] Try to generate a signed URL for object publishing in Python (boto3)
I searched for the skills needed to become a web engineer in Python
Turn multiple lists with a for statement at the same time in Python
About Python for loops
Simple gRPC in Python
Tool to make mask image for ETC in Python
[For beginners] How to use say command in python!
Parse a JSON string written to a file in Python
How to convert / restore a string with [] in python
I want to embed a variable in a Python string
I want to easily implement a timeout in python
Try to make a Python module in C language
Write a super simple molecular dynamics program in python