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

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


当前回答

我用这种方式来创建MxN矩阵,其中m = number(行)和n = number(列)。

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

其他回答

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

这种方式比嵌套的列表推导更快

[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返回Foo

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

我用这种方式来创建MxN矩阵,其中m = number(行)和n = number(列)。

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

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

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