簡體   English   中英

如何在 Python 中初始化一個二維數組?

[英]How to initialize a two-dimensional array in 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 = []

它給出了預期的結果,但感覺像是一種解決方法。 有沒有更簡單/更短/更優雅的方法來做到這一點?

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

不要使用[[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)]

效果很好。

您可以使用列表理解

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)

這種方式比嵌套列表理解更快

[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是 mutable ,你不能使用這個方案。,你必須使用

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

或假設一個類(或函數) Foo返回foo s

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

在 Python 中初始化二維數組:

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

通常,當您想要多維數組時,您不需要一個列表列表,而是一個 numpy 數組或可能的 dict。

例如,使用 numpy 你會做類似的事情

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

你可以這樣做:

[[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']]
twod_list = [[foo for _ in range(m)] for _ in range(n)]

因為 n 是行數,m 是列數,foo 是值。

如果它是一個人口稀少的數組,則最好使用以元組為鍵的字典:

dict = {}
key = (a,b)
dict[key] = value
...
t = [ [0]*10 for i in [0]*10]

對於每個元素,將創建一個新的[0]*10 ..

代碼:

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必須是不可變的。

使用最簡單的想法來創建它。

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

不正確的方法:[[無*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

要初始化二維數組,請使用: arr = [[]*m for i in range(n)]

實際上, arr = [[]*m]*n將創建一個二維數組,其中所有 n 個數組都指向同一個數組,因此任何元素中值的任何變化都將反映在所有 n 個列表中

更多解釋請訪問: https : //www.geeksforgeeks.org/python-using-2d-arrays-lists-the-right-way/

用 0 初始化一個大小為 m X n 的二維矩陣

m,n = map(int,input().split())
l = [[0 for i in range(m)] for j in range(n)]
print(l)
Matrix={}
for i in range(0,3):
  for j in range(0,3):
    Matrix[i,j] = raw_input("Enter the matrix:")

如果使用numpy ,則可以輕松創建二維數組:

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]])
row=5
col=5
[[x]*col for x in [b for b in range(row)]]

以上將為您提供一個 5x5 二維數組

[[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 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]] --> 與 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]] --> x=2 第三次迭代
[[3]*5 for x in [0,1,2,3,4]] --> with x=3 第四次迭代
[[4]*5 for x in [0,1,2,3,4]] --> with x=4 第 5 次迭代

正如@Arnab 和@Mike 指出的那樣,數組不是列表。 很少有區別是 1) 數組在初始化期間是固定大小 2) 數組通常支持比列表更少的操作。

在大多數情況下可能有點矯枉過正,但這里有一個基本的二維數組實現,它利用 python ctypes(c libraries) 的硬件數組實現

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

我理解的重要一點是:在初始化數組(在任何維度)時,我們應該為數組的所有位置提供一個默認值。 然后只有初始化完成。 之后,我們可以更改或接收新值到數組的任何位置。 下面的代碼非常適合我

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)

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

初始化所有矩陣 m=rows 和 n=columns

這是我發現的最好的教學新程序員,並且不使用額外的庫。 不過我想要更好的東西。

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

這是一個更簡單的方法:

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

要使用任何“x”值初始化所有單元格,請使用:

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

我經常使用這種方法來初始化一個二維數組

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

添加維度的一般模式可以從這個系列中得出:

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)

我開始使用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 = []

它給出了預期的結果,但是感覺像是一種解決方法。 有沒有更簡單/更短/更優雅的方式來做到這一點?

另一種方法是使用字典來保存二維數組。

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

這只能保存任何一維、二維值,並將其初始化為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

對於那些對為什么[['']*m]*n不好用感到困惑的人。 Python 使用引用調用,因此在上述情況下更改一個值也會導致其他索引值的更改。

最好的方法是[['' for i in range(m)] for j in range(n)]
這將解決所有問題。

更多清關示例:

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

我用這種方式創建 mXn 矩陣

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

一個空的二維矩陣可以用以下方式初始化:

溫度=[[],[]]

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM