将重复的 if 语句转换为循环

Converting repetitive if statements into a loop

我有这个代码:

#!/usr/bin/python3

def contract(e, i, c, n):
    l = len(e)
    grid = [[0 for i in range(i + 1)] for x in range(l)]

    for num1, row1 in enumerate(grid):
            row1[0] = e[num1] #add exponents

    for num2, row2 in enumerate(grid):
            if 0 <= num2 < n[0]:
                    grid[num2][1] = c[num2]
            if n[0] <= num2 < n[0] + n[1]:
                    grid[num2][2] = c[num2]
            if n[0] + n[1] <= num2 < n[0] + n[1] + n[2]:
                    grid[num2][3] = c[num2]

    for g in grid:
            print(g)

e = [0, 1, 2, 3]
i = 3
c = [4, 5, 6, 7]
n = [1, 2, 1]

contract(e, i, c, n)

这段代码的想法是我有一个维度为 len(e) x (i + 1) 的二维网格。第一列包含指数 e。其余列应包含系数 c,以便 n 确定系数在网格中的位置。例如,由于 n[0] = 1,网格中第 1 列第 0 行包含数字 4。n 中的下一个元素是 2,因此网格中的下一列(第 2 列)应包含 2 个数字,表示我之前使用的行下方的行中的数字 5 和 6(表示第 1 行和第 2 行,因为第 0 行已被使用)。 n[2] = 1所以grid[3][3] = 7,等等

我用重复的 if 语句实现了这个,代码工作正常,输出应该是这样的:

[0, 4, 0, 0]
[1, 0, 5, 0]
[2, 0, 6, 0]
[3, 0, 0, 7]

但是,我想制作一个可扩展程序,可以对任意数量的系数和指数执行此操作。如何将那些重复的 if 语句转换为单个循环?

我会将它转换成一个 for 循环,跟踪到目前为止看到的元素的总和,如果不等式在该迭代中成立,则调整相应的元素:

for num2, row2 in enumerate(grid):
    total = 0
    for n_idx, n_elem in enumerate(n):
        if total <= num2 < total + n_elem:
            grid[num2][n_idx + 1] = c[num2]
        total += n_elem

我建议不要在此循环中使用 sum(),因为它会在每次迭代时从头开始重新计算总和,效率不高。

使用循环对 n 列表的连续切片求和。

for num2, row2 in enumerate(grid):
    for idx in range(len(n)):
        if sum(n[:idx]) <= num2 < sum(n[:idx+1]):
            grid[num2][idx+1] = c[num2]

这是您编写的代码到循环的直接映射,如果 n 不会变得太大,这是合理的。 BrokenBenchmark 的答案经过优化,以利用每个切片的总和是前一个切片加上当前元素的总和这一事实。