I don't understand the output you want with a 3-dimensional list (list of lists of lists), but hopefully, this can be a good start.
def to_eq(coeffs: list, column_sum: bool = False, var: str = 'x') -> str:
if column_sum: # Transpose the input list of lists
coeffs = [list(k) for k in zip(*coeffs)]
output = '\n'.join(
' + '.join(var + str(j+1) + str(i+1) for j, coeff in enumerate(line))
for i, line in enumerate(coeffs)
)
else:
output = '\n'.join(
' + '.join(var + str(i+1) + str(j+1) for j, coeff in enumerate(line))
for i, line in enumerate(coeffs)
)
return output
It looks repetitive, but since you want an efficient implementation, I took the if
outside. The reversing of i
, j
to match your example can probably be made in a single line by someone with a little more creativity than me. I don't know if you actually meant that in your example though. The usual notation is to have the row first and then the column, that is, ij
.
>>> coeffs = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]]
>>> to_eq(coeffs)
x11 + x12 + x13 + x14 + x15
x21 + x22 + x23 + x24 + x25
x31 + x32 + x33 + x34 + x35
>>> to_eq(coeffs, column_sum=True)
x11 + x21 + x31
x12 + x22 + x32
x13 + x23 + x33
x14 + x24 + x34
x15 + x25 + x35
By the way, there are a ton of ways to transpose a list of lists. Check that out for other options besides what I used here.
Some tests:
>>> cols = 100000
>>> max_ = 10000000
>>> coeffs = [[i + j for i in range(cols)] for j in range(0, max_, cols)]
>>> print(len(coeffs), ' by ', len(coeffs[0]))
100 by 100000
>>> %timeit to_eq(coeffs)
5.66 s ± 90.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
>>> %timeit to_eq(coeffs, column_sum=True)
6.28 s ± 118 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
>>> cols = 1000
>>> max_ = 10000
>>> coeffs = [[i + j for i in range(cols)] for j in range(0, max_, cols)]
>>> print(len(coeffs), ' by ', len(coeffs[0]))
10 by 1000
>>> %timeit to_eq(coeffs)
5.59 ms ± 308 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> %timeit to_eq(coeffs, column_sum=True)
5.98 ms ± 111 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)