关于矩阵:如何在python中定义二维数组

How to define a two-dimensional array in Python

我想定义一个没有初始化长度的二维数组,如下所示:

1
Matrix = [][]

但它不起作用…

我试过下面的代码,但也错了:

1
Matrix = [5][5]

错误:

1
2
3
Traceback ...

IndexError: list index out of range

我犯了什么错误?


从技术上讲,您试图索引未初始化的数组。在添加项之前,必须首先用列表初始化外部列表;python调用这个"列表理解"。

1
2
3
# Creates a list containing 5 lists, each of 8 items, all set to 0
w, h = 8, 5;
Matrix = [[0 for x in range(w)] for y in range(h)]

现在可以向列表中添加项目:

1
2
3
4
5
6
7
Matrix[0][0] = 1
Matrix[6][0] = 3 # error! range...
Matrix[0][6] = 3 # valid

print Matrix[0][0] # prints 1
x, y = 0, 6
print Matrix[x][y] # prints 3; be careful with indexing!

尽管您可以根据自己的意愿命名它们,但如果您对内部和外部列表都使用"x",并且想要一个非方形矩阵,那么我会用这种方法来避免索引时可能出现的一些混乱。


如果你真的想要一个矩阵,你最好使用numpynumpy中的矩阵运算通常使用二维数组类型。创建新数组的方法有很多;最有用的方法之一是zeros函数,该函数采用shape参数并返回给定形状的数组,其值初始化为零:

1
2
3
4
5
6
7
>>> import numpy
>>> numpy.zeros((5, 5))
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

numpy也提供matrix类型。它不太常用,有些人建议不要使用它。但它对从Matlab来到numpy的人们以及其他一些环境中很有用。我想我会把它包括进来,因为我们在讨论矩阵!

1
2
3
>>> numpy.matrix([[1, 2], [3, 4]])
matrix([[1, 2],
        [3, 4]])

以下是创建二维数组和矩阵的其他一些方法(为了紧凑性删除了输出):

1
2
3
4
5
6
7
numpy.matrix('1 2; 3 4')                 # use Matlab-style syntax
numpy.arange(25).reshape((5, 5))         # create a 1-d range and reshape
numpy.array(range(25)).reshape((5, 5))   # pass a Python range and reshape
numpy.array([5] * 25).reshape((5, 5))    # pass a Python list and reshape
numpy.empty((5, 5))                      # allocate, but don't initialize
numpy.ones((5, 5))                       # initialize with ones
numpy.ndarray((5, 5))                    # use the low-level constructor


以下是初始化列表的简短符号:

1
matrix = [[0]*5 for i in range(5)]

不幸的是,将其缩短为类似于5*[5*[0]]的值并不能真正起作用,因为您最终得到了同一列表的5个副本,所以当您修改其中一个时,它们都会发生变化,例如:

1
2
3
4
5
6
>>> matrix = 5*[5*[0]]
>>> matrix
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> matrix[4][4] = 2
>>> matrix
[[0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2]]


如果要创建空矩阵,正确的语法是

1
matrix = [[]]

如果你想生成一个用0填充的5号矩阵,

1
matrix = [[0 for i in xrange(5)] for i in xrange(5)]


如果您只需要一个二维容器来容纳一些元素,那么您可以方便地使用字典:

1
Matrix = {}

然后你可以做:

1
2
Matrix[1,2] = 15
print Matrix[1,2]

这是因为1,2是一个元组,而您使用它作为索引字典的键。结果类似于一个哑稀疏矩阵。

如osa和josap valls所示,您也可以使用Matrix = collections.defaultdict(lambda:0),这样丢失的元素的默认值为0

Vatsal进一步指出,对于大型矩阵,这种方法可能不是很有效,应该只用于代码的非性能关键部分。


在python中,您将创建一个列表列表。您不必提前声明维度,但是您可以。例如:

1
2
3
4
5
matrix = []
matrix.append([])
matrix.append([])
matrix[0].append(2)
matrix[1].append(3)

现在矩阵[0][0]==2,矩阵[1][0]==3。您还可以使用列表理解语法。此示例使用它两次来构建"二维列表":

1
2
from itertools import count, takewhile
matrix = [[i for i in takewhile(lambda j: j < (k+1) * 10, count(k*10))] for k in range(10)]


接受的答案是好的和正确的,但是我花了一段时间才理解我也可以使用它来创建一个完全空的数组。

1
l =  [[] for _ in range(3)]

结果在

1
[[], [], []]

您应该列出一个列表,最好的方法是使用嵌套的理解:

1
2
3
4
5
6
7
>>> matrix = [[0 for i in range(5)] for j in range(5)]
>>> pprint.pprint(matrix)
[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0]]

在您的[5][5]示例中,您正在创建一个包含整数"5"的列表,并尝试访问其第5项,这自然会引发索引错误,因为没有第5项:

1
2
3
4
5
>>> l = [5]
>>> l[5]
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
IndexError: list index out of range


1
2
3
4
5
6
7
8
9
10
11
rows = int(input())
cols = int(input())

matrix = []
for i in range(rows):
  row = []
  for j in range(cols):
    row.append(0)
  matrix.append(row)

print(matrix)

为什么这么长的代码,在Python中也是如此?

很久以前,当我对python不满意的时候,我看到了写二维矩阵的单行答案,并告诉自己我不会再在python中使用二维矩阵。(这些单行相当吓人,它没有给我任何关于Python在做什么的信息。还要注意,我不知道这些速记。)

不管怎样,这是初学者的代码,来自C、CPP和Java背景

请注意:请不要因为我写了一个详细的代码而拒绝投票。


要声明一个由零(1)组成的矩阵,请执行以下操作:

1
numpy.zeros((x, y))

例如

1
2
3
4
>>> numpy.zeros((3, 5))
    array([[ 0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.]])

或数字(x,y)例如

1
2
3
4
>>> np.ones((3, 5))
array([[ 1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.]])

甚至三维都是可能的。(http://www.astro.ufl.edu/~warner/prog/python.html参见->多维数组)


我正在编写第一个python脚本,我对平方矩阵示例有点困惑,希望下面的示例可以帮助您节省一些时间:

1
2
 # Creates a 2 x 5 matrix
 Matrix = [[0 for y in xrange(5)] for x in xrange(2)]

以便

1
2
Matrix[1][4] = 2 # Valid
Matrix[4][1] = 3 # IndexError: list index out of range

用途:

1
matrix = [[0]*5 for i in range(5)]

第一个维度的*5起作用,因为在这个级别上,数据是不可变的。


为方便阅读而重写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 2D array/ matrix

# 5 rows, 5 cols
rows_count = 5
cols_count = 5

# create
#     creation looks reverse
#     create an array of"cols_count" cols, for each of the"rows_count" rows
#        all elements are initialized to 0
two_d_array = [[0 for j in range(cols_count)] for i in range(rows_count)]

# index is from 0 to 4
#     for both rows & cols
#     since 5 rows, 5 cols

# use
two_d_array[0][0] = 1
print two_d_array[0][0]  # prints 1   # 1st row, 1st col (top-left element of matrix)

two_d_array[1][0] = 2
print two_d_array[1][0]  # prints 2   # 2nd row, 1st col

two_d_array[1][4] = 3
print two_d_array[1][4]  # prints 3   # 2nd row, last col

two_d_array[4][4] = 4
print two_d_array[4][4]  # prints 4   # last row, last col (right, bottom element of matrix)

使用numpy可以初始化空矩阵,如下所示:

1
2
import numpy as np
mm = np.matrix([])

然后像这样附加数据:

1
mm = np.append(mm, [[1,2]], axis=1)


我在逗号分隔的文件中阅读如下:

1
2
3
4
data=[]
for l in infile:
    l = split(',')
    data.append(l)

然后,列表"data"是包含索引数据的列表[行][列]


这就是我通常在Python中创建二维数组的方式。

1
2
3
col = 3
row = 4
array = [[0] * col for _ in range(row)]

我发现,与在列表理解中使用for循环相比,这种语法很容易记住。


如果您希望能够将其视为一个二维数组,而不是被迫根据列表列表进行思考(在我看来更自然),您可以执行以下操作:

1
2
3
import numpy
Nx=3; Ny=4
my2Dlist= numpy.zeros((Nx,Ny)).tolist()

结果是一个列表(不是一个numpy数组),您可以用数字、字符串等覆盖各个位置。


这就是字典的目的!

1
matrix = {}

可以用两种方式定义键和值:

1
matrix[0,0] = value

1
matrix = { (0,0)  : value }

结果:

1
2
3
   [ value,  value,  value,  value,  value],
   [ value,  value,  value,  value,  value],
   ...

用途:

1
2
3
4
5
6
7
8
9
10
import copy

def ndlist(*args, init=0):
    dp = init
    for x in reversed(args):
        dp = [copy.deepcopy(dp) for _ in range(x)]
    return dp

l = ndlist(1,2,3,4) # 4 dimensional list initialized with 0's
l[0][1][2][3] = 1

我确实认为麻木才是出路。如果您不想使用numpy,上面是一个通用的。


1
2
# Creates a list containing 5 lists initialized to 0
Matrix = [[0]*5]*5

注意这个简短的表达,请参阅@f.j答案中的完整解释。


如果在开始之前没有尺寸信息,那么创建两个一维列表。

列表1:存储行清单2:实际二维矩阵

将整行存储在第一个列表中。完成后,将列表1附加到列表2中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from random import randint


coordinates=[]
temp=[]
points=int(raw_input("Enter No Of Coordinates >"))
for i in range(0,points):
    randomx=randint(0,1000)
    randomy=randint(0,1000)
    temp=[]
    temp.append(randomx)
    temp.append(randomy)
    coordinates.append(temp)

print coordinates

输出:

1
2
Enter No Of Coordinates >4
[[522, 96], [378, 276], [349, 741], [238, 439]]

使用列表:

1
matrix_in_python  = [['Roy',80,75,85,90,95],['John',75,80,75,85,100],['Dave',80,80,80,90,95]]

使用DICT:您还可以将此信息存储在哈希表中,以便像

1
matrix = { '1':[0,0] , '2':[0,1],'3':[0,2],'4' : [1,0],'5':[1,1],'6':[1,2],'7':[2,0],'8':[2,1],'9':[2,2]};

矩阵['1']会给你0(1)次的结果

*注意:您需要处理哈希表中的冲突。


如果您需要带预定义数字的矩阵,可以使用以下代码:

1
2
3
4
5
def matrix(rows, cols, start=0):
    return [[c + start + r * cols for c in range(cols)] for r in range(rows)]


assert matrix(2, 3, 1) == [[1, 2, 3], [4, 5, 6]]

1
l=[[0]*(L) for i in range(W)]

速度将超过:

1
l = [[0 for x in range(L)] for y in range(W)]


试试这个:

1
2
3
4
5
rows = int(input('Enter rows
'
))
my_list = []
for i in range(rows):
    my_list.append(list(map(int, input().split())))