This is probably duplicate question, but I am still curious about this.
I want to make two-dimensional list in Python without numpy. So I make a list of list. Here is my code:
myList = [None] * 3
print['myList :', myList]
myMatrix = [myList] * 3
#myMatrix = [[None, None, None], [None, None, None], [None, None, None]]
print['myMatrix', myMatrix]
for i in range [0,3]:
for j in range [0, 3]:
myMatrix[i][j] = i+j
print['myMatrix[',i,'] : ', myMatrix[i]]
print[myMatrix]
print[myMatrix[0]]
print[myMatrix[1]]
print[myMatrix[2]]
I know that the statement:
myMatrix = [myList] * 3
makes the code failed to work as I expected, and it is because list is mutable object, which means myMatrix[0], myMatrix[1], myMatrix[2] will refer to the same object. A change to any of them means a change to all of them, which is not what I expected in my code. Here is the unexpected output of my code:
['myList :', [None, None, None]]
['myMatrix', [[None, None, None], [None, None, None], [None, None, None]]]
['myMatrix[', 0, '] : ', [0, 1, 2]]
['myMatrix[', 1, '] : ', [1, 2, 3]]
['myMatrix[', 2, '] : ', [2, 3, 4]]
[[2, 3, 4], [2, 3, 4], [2, 3, 4]]
[2, 3, 4]
[2, 3, 4]
[2, 3, 4]
The only solution I found is, instead of stating myMatrix = [myList] * 3, I should write:
myMatrix = [[None, None, None], [None, None, None], [None, None, None]]
That will make the code works as I expected below [the output of the program]:
['myMatrix', [[None, None, None], [None, None, None], [None, None, None]]]
['myMatrix[', 0, '] : ', [0, 1, 2]]
['myMatrix[', 1, '] : ', [1, 2, 3]]
['myMatrix[', 2, '] : ', [2, 3, 4]]
[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
[0, 1, 2]
[1, 2, 3]
[2, 3, 4]
But it's not an efficient way to define a NxN matrix, especially if N is a big number.
Does Python have an efficient way to define a NxN matrix using list of list?
I'm more familiar with C/C++, so this problem is really bugging me. Some answers will recommend me to use numpy, but at this moment I would like to learn basic Python from scratch [without importing any library]. When I use C/C++, I can work with this two-dimensional array easily, without importing any library. Asking me to use numpy when I'm just new in Python, is just like asking me to use STL when I'm just new to C.
Of course I will learn numpy later, but I want to tackle this without numpy first.
This article explains how to convert a one-dimensional array to a two-dimensional array in Python, both for NumPy arrays ndarray
and for built-in lists list
.
- Convert a one-dimensional
numpy.ndarray
to a two-dimensionalnumpy.ndarray
- Convert a one-dimensional
list
to a two-dimensionallist
- With NumPy
- Without NumPy
On the contrary, see the following article on how to convert [= flatten] a multi-dimensional array to a one-dimensional array.
- How to flatten a list of lists in Python
Convert a one-dimensional numpy.ndarray
to a two-dimensional numpy.ndarray
Use the reshape[]
method to transform the shape of a NumPy array ndarray
. Any shape transformation is possible, not limited to transforming from a one-dimensional array to a
two-dimensional array.
By using -1
, the size of the dimension is automatically calculated.
- NumPy: How to use reshape[] and the meaning of -1
import numpy as np
a = np.arange[6]
print[a]
# [0 1 2 3 4 5]
print[a.reshape[2, 3]]
# [[0 1 2]
# [3 4 5]]
print[a.reshape[-1, 3]]
# [[0 1 2]
# [3 4 5]]
print[a.reshape[2, -1]]
# [[0 1 2]
# [3 4 5]]
If you specify a shape that cannot be converted, an error is raised.
# print[a.reshape[3, 4]]
# ValueError: cannot reshape array of size 6 into shape [3,4]
# print[a.reshape[-1, 4]]
# ValueError: cannot reshape array of size 6 into shape [4]
Convert a one-dimensional list
to a two-dimensional list
With NumPy
With NumPy, you can convert list
to numpy.ndarray
and transform the shape with reshape[]
, and then return it to list
.
l = [0, 1, 2, 3, 4, 5]
print[np.array[l].reshape[-1, 3].tolist[]]
# [[0, 1, 2], [3, 4, 5]]
print[np.array[l].reshape[3, -1].tolist[]]
# [[0, 1], [2, 3], [4, 5]]
See the following article on how to convert numpy.ndarray
and list
to each other.
- Convert numpy.ndarray and list to each other
Without NumPy
Without NumPy, you can use list comprehensions,
range[]
, and slices as follows.
- List comprehensions in Python
- How to use range[] in Python
- How to slice a list, string, tuple in Python
def convert_1d_to_2d[l, cols]:
return [l[i:i + cols] for i in range[0, len[l], cols]]
l = [0, 1, 2, 3, 4, 5]
print[convert_1d_to_2d[l, 2]]
# [[0, 1], [2, 3], [4, 5]]
print[convert_1d_to_2d[l, 3]]
# [[0, 1, 2], [3, 4, 5]]
print[convert_1d_to_2d[l, 4]]
# [[0, 1, 2, 3], [4, 5]]
The first argument is the original list, and the second argument is the number of elements of the inner list [= number of columns]. If there is a remainder, a list with a different number of elements will be stored, as in the last example.
If you want to specify the number of rows:
def convert_1d_to_2d_rows[l, rows]:
return convert_1d_to_2d[l, len[l] // rows]
print[convert_1d_to_2d_rows[l, 2]]
# [[0, 1, 2], [3, 4, 5]]
print[convert_1d_to_2d_rows[l, 3]]
# [[0, 1], [2, 3], [4, 5]]
print[convert_1d_to_2d_rows[l, 4]]
# [[0], [1], [2], [3], [4], [5]]
The function in this example is just a simple one. If not divisible, the result is different from the specified number of rows, as in the last example.