如何在Python中初始化一个二维数组?

我开始使用python,我尝试使用一个二维列表,我开始在每个地方都用相同的变量填充。我想到了这个:

def initialize_twodlist(foo):
twod_list = []
new = []
for i in range (0, 10):
for j in range (0, 10):
new.append(foo)
twod_list.append(new)
new = []

它给出了预期的结果,但感觉像是一种变通方法。有更简单/更短/更优雅的方法吗?

1016919 次浏览
[[foo for x in xrange(10)] for y in xrange(10)]

通常,当你想要多维数组时,你不想要一个列表的列表,而是一个numpy数组,或者可能是一个dict。

例如,使用numpy可以执行如下操作

import numpy
a = numpy.empty((10, 10))
a.fill(foo)

你可以使用列表理解:

x = [[foo for i in range(10)] for j in range(10)]
# x is now a 10x10 array of 'foo' (which can depend on i and j if you want)

Python中经常出现的一个模式是

bar = []
for item in some_iterable:
bar.append(SOME EXPRESSION)

这有助于推动列表推导式的引入,它将代码片段转换为

bar = [SOME_EXPRESSION for item in some_iterable]

这样更简短,有时也更清楚。通常,您会养成识别这些循环的习惯,并经常用推导式替换循环。

您的代码遵循此模式两次

twod_list = []                                       \
for i in range (0, 10):                               \
new = []                  \ can be replaced        } this too
for j in range (0, 10):    } with a list          /
new.append(foo)       / comprehension        /
twod_list.append(new)                           /

这样比较快比嵌套的列表推导式

[x[:] for x in [[foo] * 10] * 10]    # for immutable foo!

下面是一些python3计时,用于小型和大型列表

$python3 -m timeit '[x[:] for x in [[1] * 10] * 10]'
1000000 loops, best of 3: 1.55 usec per loop


$ python3 -m timeit '[[1 for i in range(10)] for j in range(10)]'
100000 loops, best of 3: 6.44 usec per loop


$ python3 -m timeit '[x[:] for x in [[1] * 1000] * 1000]'
100 loops, best of 3: 5.5 msec per loop


$ python3 -m timeit '[[1 for i in range(1000)] for j in range(1000)]'
10 loops, best of 3: 27 msec per loop

解释:

[[foo]*10]*10创建一个重复10次的相同对象的列表。您不能只使用这个,因为修改一个元素将修改每行中的同一元素!

x[:]等价于list(X),但更有效一点,因为它避免了名称查找。无论哪种方式,它都创建了每行的浅拷贝,所以现在所有元素都是独立的。

但所有元素都是相同的foo对象,因此如果foo是可变的,则不能使用此方案。,你必须使用

import copy
[[copy.deepcopy(foo) for x in range(10)] for y in range(10)]

或者假设类(或函数)Foo返回__abc1

[[Foo() for x in range(10)] for y in range(10)]

如果它是一个稀疏填充的数组,你可能最好使用一个以元组为键的字典:

dict = {}
key = (a,b)
dict[key] = value
...

正如@Arnab和@Mike指出的,数组不是列表。不同之处在于:1)数组在初始化时是固定大小的;2)数组通常支持比列表更少的操作。

也许在大多数情况下有点多余,但这里有一个基本的2d数组实现,它利用python ctypes(c库)实现硬件数组。

import ctypes
class Array:
def __init__(self,size,foo): #foo is the initial value
self._size = size
ArrayType = ctypes.py_object * size
self._array = ArrayType()
for i in range(size):
self._array[i] = foo
def __getitem__(self,index):
return self._array[index]
def __setitem__(self,index,value):
self._array[index] = value
def __len__(self):
return self._size


class TwoDArray:
def __init__(self,columns,rows,foo):
self._2dArray = Array(rows,foo)
for i in range(rows):
self._2dArray[i] = Array(columns,foo)


def numRows(self):
return len(self._2dArray)
def numCols(self):
return len((self._2dArray)[0])
def __getitem__(self,indexTuple):
row = indexTuple[0]
col = indexTuple[1]
assert row >= 0 and row < self.numRows() \
and col >=0 and col < self.numCols(),\
"Array script out of range"
return ((self._2dArray)[row])[col]


if(__name__ == "__main__"):
twodArray = TwoDArray(4,5,5)#sample input
print(twodArray[2,3])

这是我发现的教新程序员最好的方法,而且不需要使用额外的库。不过我想要更好的。

def initialize_twodlist(value):
list=[]
for row in range(10):
list.append([value]*10)
return list

在Python中初始化一个二维数组:

a = [[0 for x in range(columns)] for y in range(rows)]

用最简单的思路来创建这个。

wtod_list = []

并添加尺寸:

wtod_list = [[0 for x in xrange(10)] for x in xrange(10)]

或者如果我们想先声明大小。我们只使用:

   wtod_list = [[0 for x in xrange(10)] for x in xrange(10)]

你可以这样做:

[[element] * numcols] * numrows

例如:

>>> [['a'] *3] * 2
[['a', 'a', 'a'], ['a', 'a', 'a']]

但这有一个不受欢迎的副作用:

>>> b = [['a']*3]*3
>>> b
[['a', 'a', 'a'], ['a', 'a', 'a'], ['a', 'a', 'a']]
>>> b[1][1]
'a'
>>> b[1][1] = 'b'
>>> b
[['a', 'b', 'a'], ['a', 'b', 'a'], ['a', 'b', 'a']]

这里有一个更简单的方法:

import numpy as np
twoD = np.array([[]*m]*n)

要初始化所有带有任何'x'值的单元格,请使用:

twoD = np.array([[x]*m]*n
Matrix={}
for i in range(0,3):
for j in range(0,3):
Matrix[i,j] = raw_input("Enter the matrix:")

不要使用[[v]*n]*n,这是一个陷阱!

>>> a = [[0]*3]*3
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0]=1
>>> a
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

    t = [ [0]*3 for i in range(3)]

伟大的工作。

from random import randint
l = []


for i in range(10):
k=[]
for j in range(10):
a= randint(1,100)
k.append(a)


l.append(k)








print(l)
print(max(l[2]))


b = []
for i in range(10):
a = l[i][5]
b.append(a)


print(min(b))

错误方式:[[None*m]*n]

>>> m, n = map(int, raw_input().split())
5 5
>>> x[0][0] = 34
>>> x
[[34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None]]
>>> id(x[0][0])
140416461589776
>>> id(x[3][0])
140416461589776

使用这种方法,python不允许为外层列创建不同的地址空间,这将导致各种超出您预期的错误行为。

正确方法,但有例外:

y = [[0 for i in range(m)] for j in range(n)]
>>> id(y[0][0]) == id(y[1][0])
False

这是一个很好的方法,但如果你将默认值设置为None,则会有例外

>>> r = [[None for i in range(5)] for j in range(5)]
>>> r
[[None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
>>> id(r[0][0]) == id(r[2][0])
True

因此,使用这种方法正确地设置默认值。

绝对正确的:

跟随mike的双环路的回复。

t = [ [0]*10 for i in [0]*10]

对于每个元素将创建一个新的[0]*10 ..

我经常使用这种方法初始化2维数组

n=[[int(x) for x in input().split()] for i in range(int(input())]

twod_list = [[foo for _ in range(m)] for _ in range(n)]

n是行数,m是列数,foo是值。

添加维度的一般模式可以从这个系列中得出:

x = 0
mat1 = []
for i in range(3):
mat1.append(x)
x+=1
print(mat1)




x=0
mat2 = []
for i in range(3):
tmp = []
for j in range(4):
tmp.append(x)
x+=1
mat2.append(tmp)


print(mat2)




x=0
mat3 = []
for i in range(3):
tmp = []
for j in range(4):
tmp2 = []
for k in range(5):
tmp2.append(x)
x+=1
tmp.append(tmp2)
mat3.append(tmp)


print(mat3)

我理解的重要的事情是:在初始化数组(在任何维度)时,我们应该给数组的所有位置一个默认值。然后只完成初始化。在此之后,我们可以更改或接收数组的任何位置的新值。下面的代码非常适合我

N=7
F=2


#INITIALIZATION of 7 x 2 array with deafult value as 0
ar=[[0]*F for x in range(N)]


#RECEIVING NEW VALUES TO THE INITIALIZED ARRAY
for i in range(N):
for j in range(F):
ar[i][j]=int(input())
print(ar)


如果你使用numpy,你可以很容易地创建2d数组:

import numpy as np


row = 3
col = 5
num = 10
x = np.full((row, col), num)

x

array([[10, 10, 10, 10, 10],
[10, 10, 10, 10, 10],
[10, 10, 10, 10, 10]])
初始化一个二维数组使用: arr = [[]*m for i in range(n)] < / p > < p >其实, arr = [[]*m]*n将创建一个2D数组,其中所有n个数组都指向同一个数组,因此任何元素的任何值变化都将反映在所有n个列表

更多详细说明请访问:https://www.geeksforgeeks.org/python-using-2d-arrays-lists-the-right-way/

row=5
col=5
[[x]*col for x in [b for b in range(row)]]

上面会给你一个5x5的2D数组

[[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4]]

它使用嵌套的列表推导式。 分解如下:

[[x]*col for x in [b for b in range(row)]]

[x]*col——>被求值的最终表达式 对于——>中的x, x将是迭代器
提供的值 [b for b in range(row)]]——>迭代器

[b for b in range(row)]]这将计算为[0,1,2,3,4],因为row=5
现在简化为

[[x]*col for x in [0,1,2,3,4]]

这将计算为 [[0]*5 for x in[0,1,2,3,4]]——> with x=0第一次迭代
. [[1]*5 for x in[0,1,2,3,4]]——> with x=1第二次迭代
. [[2]*5 for x in[0,1,2,3,4]]——> with x=2第三次迭代
. [[3]*5 for x in[0,1,2,3,4]]——> with x=3第4次迭代
. [[4] * 5 x[0, 1, 2, 3, 4]]——> x = 4 5迭代< br > < / p >

lst=[[0]*n]*m
np.array(lst)

初始化所有矩阵m=行和n=列

另一种方法是使用字典来保存二维数组。

twoD = {}
twoD[0,0] = 0
print(twoD[0,0]) # ===> prints 0

它可以保存任何1D、2D值,要将其初始化为0或任何其他int值,请使用集合

import collections
twoD = collections.defaultdict(int)
print(twoD[0,0]) # ==> prints 0
twoD[1,1] = 1
print(twoD[1,1]) # ==> prints 1

代码:

num_rows, num_cols = 4, 2
initial_val = 0
matrix = [[initial_val] * num_cols for _ in range(num_rows)]
print(matrix)
# [[0, 0], [0, 0], [0, 0], [0, 0]]

initial_val必须是不可变的。

初始化一个大小为m X n的二维矩阵,取值为0

m,n = map(int,input().split())
l = [[0 for i in range(m)] for j in range(n)]
print(l)
< p > 对于那些困惑为什么[['']*m]*n不好用的人。 < br > Python使用引用调用,因此改变上述情况中的一个值也会导致其他索引值的改变。

最好的方法是[['' for i in range(m)] for j in range(n)]
这将解决所有问题。

For more澄清
例子:< / p >

>>> x = [['']*3]*3
[['', '', ''], ['', '', ''], ['', '', '']]
>>> x[0][0] = 1
>>> print(x)
[[1, '', ''], [1, '', ''], [1, '', '']]
>>> y = [['' for i in range(3)] for j in range(3)]
[['', '', ''], ['', '', ''], ['', '', '']]
>>> y[0][0]=1
>>> print(y)
[[1, '', ''], ['', '', ''], ['', '', '']]

我用这种方式来创建MxN矩阵,其中m = number(rows)n = number(columns)

arr = [[None]*(n) for _ in range(m)]

一个空的2D矩阵可以用以下方式初始化:

temp = [[], []]