将重复的 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 的答案经过优化,以利用每个切片的总和是前一个切片加上当前元素的总和这一事实。
我有这个代码:
#!/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 的答案经过优化,以利用每个切片的总和是前一个切片加上当前元素的总和这一事实。