具有不同范围的任意嵌套forloops(python)

2024-09-26 18:05:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在研究一种最终具有分形性质的模式。我编写了一个函数来处理n=4的情况。它看起来像这样:

    def enumerate_pattern(vector, n):
        path_len = len(vector)
        output = []
        for x in range(path_len-(n-1)):
            s1 = shifter(vector, 0, x)
            for y in range(path_len-(x+(n-1))):
                s2 = shifter(s1, x+1, y)
                for z in range(path_len-(x+y+(n-1))):
                    s3 = shifter(s2, x+y+2, z)
                    for w in range(path_len-(x+y+z+(n-1))):
                        s4 = shifter(s3, x+y+z+3, w)
                        some_function(s4) #which fills output
        return output

我试图把它推广到任何n,但我有一个困难的时候。有一种模式,但有点复杂。我在这个网站上找到了一个固定范围长度的递归解决方案,并试图使其适应我的情况

def loop_rec(y, n):
    if n >= 1:
        for x in range(y):
            loop_rec(y, n - 1)
    else:
       whatever()

在我的例子中,whatever()应该对应于某个函数(s4)。但我不知道如何使范围随每个级别而变化。第i级的For循环如下所示:

for L_i in range(path_len - (L_1+L_2+L_3+...+L_(i-1)+(n-1))):
   s_i = shifter(s_(i-1), L_1+L_2+L_3+...+L_(i-1)+(i-1), L_i)

Tags: path函数inforoutputlendef模式
2条回答

我想我明白了。Joonyong已经给出了一个重要的特性:必须在递归函数中携带For索引作为附加参数。函数调用不匹配的原因是,在我的例子中,每轮从范围中减去的n-1部分需要保持不变。这就是为什么我得到了对某个函数()的更高的函数调用。我通过将该数字与初始vec长度捆绑在一起解决了这个问题

这是我想到的。我使用了两个函数。一个设定初始条件。另一个生成任意数量的For循环,范围可变。我还包括了shifter函数和print语句,以便您可以看到模式

from copy import deepcopy

#shifts given element and all later elements over by some amount
def shifter(sequence, given_position, shift):
    sl_copy = deepcopy(sequence)
    sl_stored = deepcopy(sequence)
    for position in range(given_position,len(sl_copy)-shift):
        sl_copy[position+shift] = sl_stored[position]
    for element in range(given_position, len(sl_copy)-shift):
        if element < given_position + shift:
            sl_copy[element] = 0     
    return sl_copy

#recursive function to generate arbirary number of For loops
def enum_st_rec(states, shifts, base_vec, path_len, n, adjust=0, 
            counter=0):
    if n > 0:
        for i in range(path_len - adjust):
            shifts[counter+1] = shifter(shifts[counter], 
                                             adjust+counter, i)
            enum_st_rec(states, shifts, base_vec, path_len, n-1, 
                         adjust+i, counter+1)
    else:
        print(shifts[counter])
        stack = [[],[]]
        for i in range(len(base_vec)):
            if (shifts[counter][i] != 0 or base_vec[i] != 0):
                stack[0].append(shifts[counter][i])
                stack[1].append(base_vec[i])                             
        if stack not in states:
            states.append(stack)
    return states

#uses shifter function, enum_st_rec    
def enumerate_states(vec, base_vec, n):
    path_len = len(vec) - (n-1)
    states = []
    shifts = list(range(0,n+1))
    shifts[0] = list(vec)
    
    enum_st_rec(states, shifts, base_vec, path_len, n)
    
    return states

#example
vec = [1,2,3,0,0,0,0,0,0,0,0,0,0,0,0]
base_vec = [0,0,0,1,0,0,0,2,0,0,0,3,0,0,0]

output = enumerate_states(vec, base_vec, 3)

print(output)

可以将变化部分作为参数携带

def loop_rec(y, n, to_subtract=0):

    if n >= 1:
        for i in range(y - (to_subtract + (n - 1))):
            loop_rec(y, n - 1, to_subtract + i)
    else:
        whatever()

相关问题 更多 >

    热门问题