Reputation: 1793
I'm trying to create a square matrix, given an integer input.
For example:
# for n=3
m = [[1, 2, 3], [4, 5, 6],[7, 8, 9]]
my attempt:
m = list(list(range(1*i,(n+1)*i,i)) for i in range(1,n+1))
print(m)
prints this result:
[[1, 2, 3], [2, 4, 6], [3, 6, 9]]
The array must be square and consist of sequential integers.
Upvotes: 4
Views: 1654
Reputation: 2161
i rather use numpy (IT IS NOT A LIST so i know it's not the required OP, however it can still be interesting)
def func(n):
l = np.asarray([i for i in range(1,n**2+1)])
return l.reshape(n,n)
func(3)
>>> array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
take also in consideration the time to compute:
def func(n):
t = time.time()
np.arange(1, n**2 + 1).reshape((n, n))
t1 = time.time()-t
t = time.time()
np.asarray([i for i in range(1,n**2+1)]).reshape(n,n)
t2 = time.time()-t
t = time.time()
[list(range(1+n*i, 1+n*(i+1))) for i in range(n)]
t3 = time.time()-t
t = time.time()
itr = itertools.count(1) # start counting at 1
matrix = [[next(itr) for _ in range(n)] for _ in range(n)]
t4 = time.time()-t
return [t1,t2,t3,t4]
plt.plot([re[0] for re in res],'r',label = 'numpy')
plt.plot([re[1] for re in res],'b',label = 'asarray')
plt.plot([re[2] for re in res],'m',label = 'list')
plt.plot([re[3] for re in res],'g',label = 'itertool')
plt.legend()
plt.savefig('plt1.png')
will give the following graph for 200 points:
for large matrix, go straight for the numpy solution of @jpp
Upvotes: 1
Reputation: 1228
You can use comprehensive lists. For a zero-filled matrix:
mat = [[0 for i in range(N)] for i in range(N)]
For a matrix with consecutive elements (zero-based):
mat = [[(N*j + i) for i in range(N)] for j in range(N)]
For a matrix with consecutive elements (one-based):
mat = [[(N*j + i +1) for i in range(N)] for j in range(N)]
And for a square print you can use:
>>> print(*mat,sep="\n")
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
Upvotes: 0
Reputation: 43326
You can use itertools.count
to create an iterator that yields ascending numbers, and then advance that iterator in a nested list comprehension using the next
function:
import itertools
n = 3
itr = itertools.count(1) # start counting at 1
matrix = [[next(itr) for _ in range(n)] for _ in range(n)]
# result: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Upvotes: 1
Reputation: 164843
Here's one way:
n = 3
m = [list(range(1+n*i, 1+n*(i+1))) for i in range(n)]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
The main misunderstanding appears to be in spotting the pattern. For example, the first value in each column can be computed via 1 + 3 * i
, where i
iterates over 0, 1, 2
. For the end
argument of range
, you just need to add n to the formula, and we can use the identity:
n*i + n = n*(i+1)
As an aside, if you are happy to use a 3rd party library, this is trivial with NumPy:
import numpy as np
n = 3
A = np.arange(1, n**2 + 1).reshape((n, n))
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Upvotes: 1