Reputation: 324
I have this code:
#!/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)
The idea of this code is that I have a 2 dimensional grid that has dimensions len(e) x (i + 1)
. The first column contains exponents e
. The rest of the columns should contain coefficients c
in such a way that n
determines the positions of the coefficients in the grid. For example, since n[0] = 1
, column 1, row 0 in the grid contains number 4. The next element in n
is 2, so the next column in the grid (column 2) should contain 2 numbers, meaning numbers 5 and 6 in rows below the row that I used previously (meaning rows 1 and 2 because row 0 is already used). n[2] = 1
so grid[3][3] = 7
, etc.
I implemented this with repetitive if-statements and the code works fine, the output is as it should be:
[0, 4, 0, 0]
[1, 0, 5, 0]
[2, 0, 6, 0]
[3, 0, 0, 7]
However, I would like to make an extensible program that can do this for any number of coefficients and exponents. How can I convert those repetitive if statements to a single loop?
Upvotes: 1
Views: 106
Reputation: 782564
Use a loop that sums successive slices of the n
list.
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]
This is a direct mapping of the code you wrote to a loop, and reasonable if n
doesn't get too large. BrokenBenchmark's answer is optimized to take advantage of the fact that the sum of each slice is the sum of the previous slice plus the current element.
Upvotes: 1
Reputation: 19262
I would convert it into a for
loop that keeps track of the sum of the elements seen so far, adjusting the corresponding element if the inequality holds for that iteration:
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
I would advise against using sum()
in this loop, as it recomputes the sum from scratch on each iteration, which isn't very efficient.
Upvotes: 1