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

时间:2010-03-07 17:27:55

标签: python multidimensional-array

我正在开始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 = []

它给出了期望的结果,但感觉就像一个解决方法。是否有更简单/更短/更优雅的方式来做到这一点?

31 个答案:

答案 0 :(得分:337)

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)                           /

答案 1 :(得分:181)

您可以使用list comprehension

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)

答案 2 :(得分:121)

这种方式比嵌套列表推导

更快
[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是可变的,则无法使用此方案。您必须使用< / p>

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

或假设一个返回Foo s

的类(或函数)foo
[[Foo() for x in range(10)] for y in range(10)]

答案 3 :(得分:67)

不要使用[[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表示范围(3)中的i] 很棒

答案 4 :(得分:50)

在Python中初始化二维数组:

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

答案 5 :(得分:24)

[[foo for x in xrange(10)] for y in xrange(10)]

答案 6 :(得分:20)

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

例如,对于numpy,你会做类似

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

答案 7 :(得分:13)

你可以这样做:

[[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']]

答案 8 :(得分:8)

如果它是一个人口稀少的数组,你可能最好使用一个用元组键入的字典:

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

答案 9 :(得分:4)

代码:

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必须是不可变的。

答案 10 :(得分:4)

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

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

答案 11 :(得分:3)

方法不正确:[[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

因此,请使用此方法正确设置默认值。

绝对正确:

按照迈克对double loop的回复。

答案 12 :(得分:3)

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

每个元素都会创建一个新的[0]*10 ..

答案 13 :(得分:3)

使用最简单的想法来创建它。

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)]

答案 14 :(得分:2)

用0初始化大小为m X n的2D矩阵

m,n = map(int,input().split())
l = [[0 for i in range(m)] for j in range(n)]
print(l)

答案 15 :(得分:2)

您可以尝试使用此[[0] * 10] * 10。这将返回10d行和10列的2d数组,每个单元格的值为0。

答案 16 :(得分:2)

Matrix={}
for i in range(0,3):
  for j in range(0,3):
    Matrix[i,j] = raw_input("Enter the matrix:")

答案 17 :(得分:2)

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->求值的最终表达式
for x in-> x将是迭代器提供的值
[b表示范围(行)中的b]]->迭代器。

[b在范围(行)中为b的b]],由于row = 5,其结果将为[0,1,2,3,4] 所以现在简化为

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

这将评估为 [[0,*,3,4]中x的[[0] * 5]-> x = 0第一次迭代
[[1] * 5 for x in [0,1,2,3,4]]-> x = 1第二次迭代
[[2] * 5 for x in [0,1,2,3,4]]-> x = 2第三次迭代
[[3] * 5 for x in [0,1,2,3,4]]-> x = 3第4次迭代
[[4] * 5 for x in [0,1,2,3,4]]-> x = 4第5次迭代

答案 18 :(得分:1)

正如@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])

答案 19 :(得分:0)

如果使用 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]])

答案 20 :(得分:0)

我用这种方式创建 mXn 矩阵

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

答案 21 :(得分:0)

对于那些对为什么 [['']*m]*n 不好用感到困惑的人。 Python 使用引用调用,因此在上述情况下更改一个值也会导致其他索引值的更改。

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

更多清关 示例:

>>> x = [['']*3]*3
[['', '', ''], ['', '', ''], ['', '', '']]
>>> x[0][0] = 1
>>> x
[[1, '', ''], [1, '', ''], [1, '', '']]

答案 22 :(得分:0)

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

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

这只能保存任何1D,2D值,并将其初始化为0或任何其他int值,请使用 collections

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

答案 23 :(得分:0)

lst = [[0] * m对于范围(n)中的i]

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

答案 24 :(得分:0)

要初始化二维数组,请使用: arr = [[]*m for i in range(n)]

实际上, arr = [[]*m]*n将创建一个2D数组,其中所有n个数组都指向同一数组,因此任何元素中值的任何变化都将反映在所有n个列表中

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

答案 25 :(得分:0)

我了解的重要一点是:在初始化数组(任何维度)时,我们应该为数组的所有位置提供默认值。然后,仅初始化完成。之后,我们可以更改或接收新值到数组的任何位置。以下代码非常适合我

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)

答案 26 :(得分:0)

可以从以下系列中得出添加尺寸的一般模式:

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)

答案 27 :(得分:0)

这是我在教授新程序员时所发现的最好的,而且没有使用额外的库。我想要更好的东西。

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

答案 28 :(得分:0)

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

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

答案 29 :(得分:0)

这是一种更简单的方法:

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

用任何&#39; x&#39;初始化所有单元格。价值使用:

twoD = np.array([[x]*m]*n

答案 30 :(得分:-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))