How to initialize a two-dimensional array in Pytho

2019-01-01 07:51发布

I'm beginning python and I'm trying to use a two-dimensional list, that I initially fill up with the same variable in every place. I came up with this:

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

It gives the desired result, but feels like a workaround. Is there an easier/shorter/more elegant way to do this?

20条回答
步步皆殇っ
2楼-- · 2019-01-01 08:14

You can use a 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)
查看更多
琉璃瓶的回忆
3楼-- · 2019-01-01 08:15
twod_list = [[foo for _ in range(m)] for _ in range(n)]

for n is number of rows, and m is the number of column, and foo is the value.

查看更多
余生无你
4楼-- · 2019-01-01 08:16

Incorrect Approach: [[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

With this approach, python does not allow creating different address space for the outer columns and will lead to various misbehaviour than your expectation.

Correct Approach but with exception:

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

It is good approach but there is exception if you set default value to 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

So set your default value properly using this approach.

Absolute correct:

Follow the mike's reply of double loop.

查看更多
唯独是你
5楼-- · 2019-01-01 08:18

To initialize a two-dimensional array in Python:

a = [[0 for x in range(columns)] for y in range(rows)]
查看更多
ら面具成の殇う
6楼-- · 2019-01-01 08:19

You can do just this:

[[element] * numcols] * numrows

For example:

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

But this has a undesired side effect:

>>> 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']]
查看更多
步步皆殇っ
7楼-- · 2019-01-01 08:19

As @Arnab and @Mike pointed out, an array is not a list. Few differences are 1) arrays are fixed size during initialization 2) arrays normally support lesser operations than a list.

Maybe an overkill in most cases, but here is a basic 2d array implementation that leverages hardware array implementation using 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])
查看更多
登录 后发表回答