如何在Python中定义二维数组

Mas*_*ian 665 python matrix syntax-error

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

Matrix = [][]
Run Code Online (Sandbox Code Playgroud)

但它不起作用......

我已经尝试了下面的代码,但它也是错误的:

Matrix = [5][5]
Run Code Online (Sandbox Code Playgroud)

错误:

Traceback ...

IndexError: list index out of range
Run Code Online (Sandbox Code Playgroud)

我的错是什么?

Man*_*y D 940

您在技术上尝试索引未初始化的数组.在添加项目之前,您必须首先使用列表初始化外部列表; Python称之为"列表理解".

# 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)] 
Run Code Online (Sandbox Code Playgroud)

您现在可以将项目添加到列表中:

Matrix[0][0] = 1
Matrix[6][0] = 3 # error! range... 
Matrix[0][6] = 3 # valid
Run Code Online (Sandbox Code Playgroud)

虽然您可以按照自己的意愿命名它们,但我这样看是为了避免索引时可能出现的混乱,如果对内部和外部列表使用"x",并且想要非方形矩阵.

  • 对于范围(行数)中的x,[[0表示范围内的x(cols_count)]] (205认同)
  • @ 6packkid`[0]*w`部分很好,但是`[[0]*w]*h]`会产生意想不到的行为.试试`mat = [[0]*3]*3; mat [0] [1] = 10; print(mat == [[0,10,0],[0,10,0,[0,10,0]])`和`mat = [[0]*3 for i in range(3)] ; mat [0] [1] = 10; print(mat == [[0,10,0],[0,0,0],[0,0,0]])`. (9认同)
  • @dave如果你不需要零填充,可以使用`range`直接创建内部列表:``[范围(5)中的x的范围(5)]`` (4认同)
  • 由ademar111190编辑.在Python 3中没有xrange,但如果你必须使用Python 2,那么如果你不想不必要地创建对象,xrange是正确的函数. (3认同)
  • @alanjds - 这是真的,但你仍然在Python 2中为外部迭代创建了许多不必要的对象引用(尝试使用非常大的范围).此外,初始化到某个值几乎总是你想要的 - 这通常是0.范围产生一个可迭代的集合 - xrange返回一个生成器.我的观点是,阿德玛"纠正"了一些实际上比纠正更为正确和有效的东西. (2认同)
  • 不会更简洁吗?:````[[0]*w]*h``` (2认同)
  • @6packkid 这使用 *same* 数组 h 次(因此更改一个会影响所有行)。尝试例如`test = [[0]*3]*5; 测试[1][1]=7;打印(测试)` (2认同)

sen*_*rle 379

如果你真的想要一个矩阵,你可能会更好numpy.矩阵运算numpy通常使用具有两个维度的数组类型.创建新数组的方法有很多种; 其中最有用的是zeros函数,它接受一个shape参数并返回给定形状的数组,其值初始化为零:

>>> 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.]])
Run Code Online (Sandbox Code Playgroud)

numpy也提供了一种matrix类型.它不太常用,有些人建议不要使用它.但它对于numpy来自Matlab以及其他一些环境的人来说很有用.因为我们在谈论矩阵,所以我想我会把它包括在内!

>>> numpy.matrix([[1, 2], [3, 4]])
matrix([[1, 2],
        [3, 4]])
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

  • 无论什么时候你想要矩阵,你都想使用numpy.这个答案应该是第一个. (72认同)
  • 问题使用英语单词“ matrix”的事实并不意味着他们应该使用`np.matrix`来表示它。用numpy表示矩阵的正确方法是使用“数组”。 (2认同)
  • @jpp,正如之前的帖子所说,来自 matlab 的人可能会发现它很有用。但是“numpy”文档现在表明该类将来可能会被弃用和[删除](https://docs.scipy.org/doc/numpy/reference/ generated/numpy.matrix.html),所以我'已将其从答案中删除。 (2认同)

And*_*ark 315

以下是初始化列表列表的简短表示法:

matrix = [[0]*5 for i in range(5)]
Run Code Online (Sandbox Code Playgroud)

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

>>> 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]]
Run Code Online (Sandbox Code Playgroud)

  • 上面的注释并不完全正确:[0]*5仍然会创建一个序列,对同一个表示数字0的引用的次数是5次.但是你永远不会注意到这一点,因为0是不可变的(我会说0表现得像一个值 - 或者你可能认为它是一种原始数据类型 - 因为它是不可变的,所以你永远不会遇到引用同一个对象而不是副本的问题.) (8认同)
  • 你能解释"缩短"失败背后的逻辑吗?为什么python在这种情况下输出相同列表的副本,在"[0]*5"的情况下输出不同单元格的数组? (3认同)
  • 更多pythonic:`[[0] * 5 for _ in range(5)]`与您未使用的匿名循环计数器 (3认同)
  • 一次性注释“不幸的是,将其缩短为 5*[5*[0]] 之类的东西并没有真正起作用”应该位于此页面的较高位置,因为它对许多人来说并不明显 (3认同)
  • 是的,python3的[文档](https://docs.python.org/3/faq/programming.html#faq-multiDimension-list)也提到了它。 (3认同)

mri*_*ard 102

如果要创建空矩阵,请使用正确的语法

matrix = [[]]
Run Code Online (Sandbox Code Playgroud)

如果你想生成一个大小为5的矩阵,填充0,

matrix = [[0 for i in xrange(5)] for i in xrange(5)]
Run Code Online (Sandbox Code Playgroud)

  • @KorayTugay因为矩阵是使用嵌套在另一个列表(列)内的Python列表(行)来表示的。 (2认同)
  • 对于 Python-3,使用 range 函数代替 xrange func (2认同)
  • 我认为 `matrix = [[]]` 然后需要 `.append` 来实际创建索引。因为否则 `matrix[0][0] = 1` 还不起作用。 (2认同)

eno*_*ram 73

如果你想要的只是一个二维容器来容纳一些元素,你可以方便地使用字典:

Matrix = {}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

Matrix[1,2] = 15
print Matrix[1,2]
Run Code Online (Sandbox Code Playgroud)

这是因为1,2它是元组,并且您将它用作索引字典的键.结果类似于哑稀疏矩阵.

如osa和Josap Valls所示,您也可以使用Matrix = collections.defaultdict(lambda:0)缺失元素的默认值0.

Vatsal进一步指出,这种方法对于大型矩阵可能效率不高,而且只能用于代码的非性能关键部分.

  • 然后,您也可以执行导入集合;Matrix = collections.defaultdict(float)`,用零代替未初始化的元素。 (2认同)
  • 不会访问元组(1,2)的字典作为密钥具有O(n)的最坏情况复杂性.在内部它会散列元组.而使用2D阵列会给访问索引[1,2]访问带来O(1)时间复杂度.所以使用dict不应该是一个好的选择. (2认同)

wbe*_*rry 38

在Python中,您将创建一个列表列表.您不必提前声明尺寸,但可以.例如:

matrix = []
matrix.append([])
matrix.append([])
matrix[0].append(2)
matrix[1].append(3)
Run Code Online (Sandbox Code Playgroud)

现在matrix [0] [0] == 2和matrix [1] [0] == 3.您还可以使用列表推导语法.此示例使用它两次来构建"二维列表":

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)]
Run Code Online (Sandbox Code Playgroud)

  • `extend`在第一种情况下也会有所帮助:如果你从`m = [[]]`开始,那么你可以用`m [0]扩展内部列表(扩展一行).extend([1, 2])`,并使用`m.append([3,4])`添加到外部列表(追加一个新行),这些操作会留下`[[1,2],[3,4] ]`. (6认同)

utd*_*mir 20

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

>>> 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]]
Run Code Online (Sandbox Code Playgroud)

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

>>> l = [5]
>>> l[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
Run Code Online (Sandbox Code Playgroud)


Fab*_*ian 20

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

l =  [[] for _ in range(3)]
Run Code Online (Sandbox Code Playgroud)

结果是

[[], [], []]
Run Code Online (Sandbox Code Playgroud)


unk*_*ror 19

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)
Run Code Online (Sandbox Code Playgroud)

为什么这么长的代码,Python你问的那个?

很久以前,当我对Python不熟悉时,我看到单行答案是为了编写2D矩阵,并告诉自己我不会再在Python中使用二维矩阵.(那些单行非常可怕,它没有给我任何有关Python正在做什么的信息.另请注意,我不知道这些简写.)

无论如何,这里是来自C,CPP和Java背景的初学者的代码

Python爱好者和专家的注意事项:请不要因为我写了详细的代码而拒绝投票.


kha*_*haz 11

声明一个零(一)的矩阵:

numpy.zeros((x, y))
Run Code Online (Sandbox Code Playgroud)

例如

>>> numpy.zeros((3, 5))
    array([[ 0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.]])
Run Code Online (Sandbox Code Playgroud)

或numpy.ones((x,y))例如

>>> np.ones((3, 5))
array([[ 1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.]])
Run Code Online (Sandbox Code Playgroud)

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


inn*_*ov8 11

使用:

matrix = [[0]*5 for i in range(5)]
Run Code Online (Sandbox Code Playgroud)

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

  • 我可能将其写为`matrix = [[0] * cols for _ in range(rows)]` (3认同)

Man*_*ddy 11

重写易于阅读:

# 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)
Run Code Online (Sandbox Code Playgroud)


use*_*954 10

我正在使用我的第一个Python脚本,我对方阵示例感到有些困惑,所以我希望下面的示例可以帮助您节省一些时间:

 # Creates a 2 x 5 matrix
 Matrix = [[0 for y in xrange(5)] for x in xrange(2)]
Run Code Online (Sandbox Code Playgroud)

以便

Matrix[1][4] = 2 # Valid
Matrix[4][1] = 3 # IndexError: list index out of range
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael 10

这就是我通常在python中创建2D数组的方法.

col = 3
row = 4
array = [[0] * col for _ in range(row)]
Run Code Online (Sandbox Code Playgroud)

与在列表推导中使用to循环相比,我发现这种语法很容易记住.


Nam*_*ani 9

使用NumPy,您可以像这样初始化空矩阵:

import numpy as np
mm = np.matrix([])
Run Code Online (Sandbox Code Playgroud)

然后追加这样的数据:

mm = np.append(mm, [[1,2]], axis=1)
Run Code Online (Sandbox Code Playgroud)


Mer*_*sud 9

您可以通过将两个或多个方括号或第三个括号([],以逗号分隔)与方括号嵌套来创建一个空的二维列表,如下所示:

Matrix = [[], []]
Run Code Online (Sandbox Code Playgroud)

现在假设你想附加 1Matrix[0][0]然后你输入:

Matrix[0].append(1)
Run Code Online (Sandbox Code Playgroud)

现在,输入 Matrix 并按 Enter。输出将是:

[[1], []]
Run Code Online (Sandbox Code Playgroud)

如果您输入以下语句

Matrix[1].append(1)
Run Code Online (Sandbox Code Playgroud)

那么矩阵将是

[[], [1]]
Run Code Online (Sandbox Code Playgroud)


wsa*_*ers 6

我用逗号分隔文件读取如下:

data=[]
for l in infile:
    l = split(',')
    data.append(l)
Run Code Online (Sandbox Code Playgroud)

列表"数据"然后是具有索引数据的列表列表[row] [col]


小智 6

如果您希望能够将其视为2D数组,而不是被迫以列表列表的方式思考(我认为这自然得多),则可以执行以下操作:

import numpy
Nx=3; Ny=4
my2Dlist= numpy.zeros((Nx,Ny)).tolist()
Run Code Online (Sandbox Code Playgroud)

结果是一个列表(不是NumPy数组),您可以用数字,字符串或其他内容覆盖各个位置。


Har*_*rma 6

l=[[0]*(L) for _ in range(W)]
Run Code Online (Sandbox Code Playgroud)

会比以下更快:

l = [[0 for x in range(L)] for y in range(W)] 
Run Code Online (Sandbox Code Playgroud)

  • 与下面已回答的答案重复。另外 `[[0]*(L) for i in range(W)]` 应该是 `[[0]*(L) for _ in range(W)]` 因为 `i` 没有在任何地方使用 (3认同)

pte*_*gon 5

使用:

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
Run Code Online (Sandbox Code Playgroud)

我确实认为NumPy是要走的路。如果您不想使用NumPy,则以上是一种通用方法。


Kou*_*zdi 5

这就是字典的用途!

matrix = {}
Run Code Online (Sandbox Code Playgroud)

您可以通过两种方式定义

matrix[0,0] = value
Run Code Online (Sandbox Code Playgroud)

要么

matrix = { (0,0)  : value }
Run Code Online (Sandbox Code Playgroud)

结果:

   [ value,  value,  value,  value,  value],
   [ value,  value,  value,  value,  value],
   ...
Run Code Online (Sandbox Code Playgroud)


Nag*_*ade 5

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

list 1: To store rows
list 2: Actual two-dimensional matrix
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

输出:

Enter No Of Coordinates >4
[[522, 96], [378, 276], [349, 741], [238, 439]]
Run Code Online (Sandbox Code Playgroud)