提问人:kxrosene 提问时间:2/11/2023 最后编辑:kxrosene 更新时间:2/12/2023 访问量:164
有没有办法在一定深度创建多个嵌套列表?
Is there a way to create multiple nested lists to a certain depth?
问:
如果问题是间接的或令人困惑的,我深表歉意。我试图实现的是一个如下所示的列表:
[[[0,0],[0,0],[0,0]],[[0,0],[0,0],[0,0]],[[0,0],[0,0],[0,0]]]
但是,我希望列表具有可变数量的列表“深度”(上面列表的列表“深度”为 3,因为它在底部最多有 3 个列表;要访问其中的项目,它看起来像`aList[1][0][1]`
)
我尝试使用列表推导:
aList = [[[[None for _ in range(3)] for _ in range(3)] for _ in range(3)] for _ in range(3)]
唯一的问题是,如果不直接编辑代码,我无法更改列表的深度。
我能做些什么来达到我想要的结果?(我试图实现的列表包含 7^4 (2401) 个项目,只是为了让您知道。
答:
2赞
Tom McLean
2/11/2023
#1
递归是你的朋友:
def nested_list(depth, size):
if depth == 1:
return [None for _ in range(size)]
return [nested_list(depth-1, size) for _ in range(size)]
评论
0赞
Kelly Bundy
2/11/2023
无法生成它们的第一个示例,因为它们的大小并不完全相同。
3赞
mozway
2/11/2023
#2
对于numpy来说,这可能是一份不错的工作:
import numpy as np
out = np.zeros((3, 3, 2), dtype=int).tolist()
输出:
[[[0, 0], [0, 0], [0, 0]],
[[0, 0], [0, 0], [0, 0]],
[[0, 0], [0, 0], [0, 0]]]
或者使用递归函数:
def nested(shape):
if shape:
n, *shape = shape
return [nested(shape) for _ in range(n)]
return 0
out = nested((3, 3, 2))
评论
0赞
kxrosene
2/11/2023
只是为了确认,我可以将 (3, 3, 2) 作为元组传入?
0赞
mozway
2/11/2023
@iCxbe yes 应该是一个元组(或可迭代)shape
0赞
Dorian Turba
2/11/2023
#3
纯python解决方案
我的建议:只有当你不能使用 numpy 时。
递归
警告,此代码很简单,但根据您的配置有深度限制。
from pprint import pprint
def list_in_depth_recursive(depth: int, length: int | None = None):
"""limited by stack size (default 500 or 1000)"""
if length is None:
length = depth
if depth <= 1:
return [None] * length
return [list_in_depth_recursive(depth - 1, length) for _ in range(length)]
pprint(list_in_depth_recursive(3))
# [[[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, None, None]]]
>>> pprint(list_in_depth_recursive(10000))
RecursionError: maximum recursion depth exceeded in comparison
迭 代
警告,由于 ,您还可以使用此代码生成 。deepcopy
RecursionError
from copy import deepcopy
from pprint import pprint
def list_in_dept_iterative(depth: int, length: int | None = None):
"""limited by memory"""
if length is None:
length = depth
if depth <= 0:
return [None]
current_depth_list = [None] * length
while depth > 1:
current_depth_list = [deepcopy(current_depth_list) for _ in range(length)]
depth -= 1
return current_depth_list
pprint(list_in_dept_iterative(3))
# [[[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, None, None]]]
评论
0赞
kxrosene
2/11/2023
我之后的列表实际上很大(7^4 = 2401),所以我不确定递归是否可以接受。谢谢你。
0赞
Kelly Bundy
2/11/2023
@iCxbe嗯?你的意思是 7×7×7×7,就像你的第一个例子是 3×3×2 一样吗?那么这不是“相当大的”,而是非常小的,没有一个解决方案会有丝毫问题。你是说别的吗?
0赞
Dorian Turba
2/12/2023
list_in_depth_recursive(4, 7) 不是问题。如果您只需要 500 或 1000+ 的深度。list_in_depth_recursive(1000) 通常是极限,所以一个更大的列表,1000^1000。
0赞
kxrosene
2/13/2023
@DorianTurba哦,好吧,这只是我不明白这个问题的一个例子。感谢您的澄清。
0赞
cards
2/11/2023
#4
一种递归方法reduce
from functools import reduce
shape = 3, 2, 5
lst = reduce(lambda row, dim: row + [[0] * dim], shape, [])
#[[0, 0, 0], [0, 0], [0, 0, 0, 0, 0]]
-2赞
Kelly Bundy
2/11/2023
#5
如果我们通过字符串进行重复数据删除,我们可以乘以:
a = eval(str([[[0]*2]*3]*3))
对于可变尺寸,例如:sizes = 2, 3, 3
n = len(sizes)
a = eval(str(eval('[' * n + '0' + ']*%d' * n % sizes)))
评论
0赞
kxrosene
2/11/2023
我认为这样做的问题在于这些值都指向相同的区域,因此当我尝试更改单个值时,多个值会同时更改,这不是我所追求的。
0赞
Kelly Bundy
2/11/2023
@iCxbe 这不是真的。重复数据删除解决了这个问题。重复数据删除代码也很难被忽视,我在文中明确指出了这一点。
0赞
kxrosene
2/11/2023
不过,还有另一个问题。如果我希望通过更改单个变量来更改深度,该怎么办?它有一个固定的深度,如果不直接编辑代码本身,就不容易改变它。如果可能的话,请提供解决方案,因为我确实指定了深度必须是可变的。
0赞
Kelly Bundy
2/11/2023
@iCxbe啊,是的,这是一个真正的问题。我实际上从一个可变版本开始,然后显然忘记了这一点。昨晚很晚了。我将添加一个变量。
0赞
Alain T.
2/12/2023
#6
递归可能是你最好的选择:
def matrix(size,*more):
return [matrix(*more) for _ in range(size)] if more else [0]*size
输出:
matrix(3,3,2)
[[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
您还可以通过拆分初始 1D 列表以针对每个维度进行细分来迭代执行此操作:
def matrix(*dims):
result = [0]
for d in dims: result *= d
for d in dims[:0:-1]:
result = [ result[i:i+d] for i in range(0,len(result),d) ]
return result
评论
[[[0,0], ...