我想初始化一个多维列表。基本上,我想要一个 10x10 网格 - 一个包含 10 个列表的列表,每个列表包含 10 个项目。
每个列表值应初始化为整数 0。
在一行中执行此操作的明显方法:
myList = [[0]*10]*10
不起作用,因为它会生成一个包含 10 个对一个列表的引用的列表,因此更改任何行中的一项会在所有行中更改它。
我看过的文档讨论了使用
[:]
来复制列表,但是在使用乘数时仍然不起作用:myList = [0]*10; myList = myList[:]*10
与 myList = [[0]*10]*10
具有相同的效果。
除了创建
myList.append()
的循环之外,是否有一种快速有效的方法来以这种方式初始化列表?
您可以通过列表理解来非常有效地做到这一点:
a = [[0] * number_cols for i in range(number_rows)]
这是一项工作......嵌套的列表理解!
[[0 for i in range(10)] for j in range(10)]
slakfdj alf aslkfjalkfj alsdf laskjdf ldajdf lkjdalsfjdalskjdf;laskjdf asfd
只是想添加一个答案,因为问题询问了一般的 n 维情况,但我认为还没有得到解答。您可以使用以下示例对任意数量的维度递归执行此操作:
n_dims = [3, 4, 5]
empty_list = 0
for n in n_dims:
empty_list = [empty_list] * n
>>>empty_list
>>>[[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]]
这是一个使用递归列表推导式适用于任意维数的函数。它不需要任何导入即可工作。
def init_list(dims, val):
if len(dims) == 0:
raise ValueError("Requires at least 1 dimension.")
if len(dims) == 1:
return [val for _ in range(dims[0])]
return [init_list(dims[1:], val=val) for _ in range(dims[0])]
示例:
>>> init_list([3, 2, 1], val=0)
[[[0], [0]], [[0], [0]], [[0], [0]]]
您实际上可能需要一个数组而不是一些列表。几乎每次我看到这种“预设大小的嵌套列表”模式时,都会发现有些事情不太正确。
我发现要明白你的意思,你需要自己
import copy
def n_dim_list(dims, init_val):
if not dims:
return []
lst = [init_val for i in range(dims[-1])]
for d in dims[::-1][1::]:
lst = [copy.deepcopy(lst) for i in range(d)]
return lst
其中dims是你想要的维度数量的长度列表,content是所需的nd-list在每个维度的大小。 不是最优雅的,但清晰并且能完成工作。
另一种方法,但使用OP's拒绝的方法。
import numpy as np
myList = [[0]*10]*10
myList = np.array(myList)
l=myList.tolist()
myList=l
输出和测试如下:
>>> l
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
>>> l[0][0]=100
>>> l
[[100, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
输出与预期的
l[0]
克隆不同。
虽然这样效率不高。 1000X1000 列表需要近 7 秒,而列表推导式只需要 0.0052158 秒。