How to make n-dimensional nested for-loops in Python? [duplicate]

倖福魔咒の 提交于 2020-01-30 05:07:51

问题


I have the following situation:

for x1 in range(x1, x2):
    for x2 in range(x3, x4):
        for x3 ...
            ...
                f(x1, x2, x3, ...)

How to convert this to a mechanism in which I only tell python to make n nested loops where the variable name is x1, x2, x3, x4, ...? I don't want to write every possibility manually of course, since there might be very many dimensions.


回答1:


What you want to do is iterate over a product. Use itertools.product.

import itertools

ranges = [range(x1, x2), range(x3, x4), ...]

for xs in itertools.product(*ranges):
    f(*xs)

Example

import itertools

ranges = [range(0, 2), range(1, 3), range(2, 4)]

for xs in itertools.product(*ranges):
    print(*xs)

Output

0 1 2
0 1 3
0 2 2
0 2 3
1 1 2
1 1 3
1 2 2
1 2 3



回答2:


Recommended: itertools

itertools is an awesome package for everything related to iteration:

from itertools import product

x1 = 3; x2 = 4
x3 = 0; x4 = 2
x5 = 42; x6 = 42
for x, y, z in product(range(x1, x2), range(x3, x4), range(x4, x5)):
    print(x, y, z)

gives

3 0 2
3 0 3
3 0 4
3 0 5
3 0 6
3 0 7
3 0 8
3 0 9
3 0 10
3 0 11
3 0 12
3 0 13
3 0 14
3 0 15
3 0 16
3 0 17
3 0 18
3 0 19
3 0 20
3 0 21
3 0 22
3 0 23
3 0 24
3 0 25
3 0 26
3 0 27
3 0 28
3 0 29
3 0 30
3 0 31
3 0 32
3 0 33
3 0 34
3 0 35
3 0 36
3 0 37
3 0 38
3 0 39
3 0 40
3 0 41
3 1 2
3 1 3
3 1 4
3 1 5
3 1 6
3 1 7
3 1 8
3 1 9
3 1 10
3 1 11
3 1 12
3 1 13
3 1 14
3 1 15
3 1 16
3 1 17
3 1 18
3 1 19
3 1 20
3 1 21
3 1 22
3 1 23
3 1 24
3 1 25
3 1 26
3 1 27
3 1 28
3 1 29
3 1 30
3 1 31
3 1 32
3 1 33
3 1 34
3 1 35
3 1 36
3 1 37
3 1 38
3 1 39
3 1 40
3 1 41

Create a cross-product function yourself

def product(*args):
    pools = map(tuple, args)
    result = [[]]
    for pool in pools:
        result = [x + [y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)



回答3:


You could also use numpy.ndindex to achieve what you are looking for:

import numpy
for y1, y2, y3 in numpy.ndindex(x2, x4, ...):
    ...

Thats especially useful when you are already using numpy for something else in your script. You would have to add the 'starting point' (i.e. x1, x2, ...) to each dimension though (if it's not 0).




回答4:


Use multiprocessing!

import multiprocessing
from itertools import product

results = [] 
def callback(return_value):
    # this stores results
    results.append(return_value)

if __name__=="__main__" :
    pool = multiprocessing.Pool(4)
    args = product(range1, range2, range)
    for x, y, z in args:
        pool.apply_async(f,(x,y,z),call_back=callback)
    pool.close()
    pool.join()

Now you can run your function while also taking advantage of the full capacity of your machine!



来源:https://stackoverflow.com/questions/50860578/how-to-make-n-dimensional-nested-for-loops-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!