基本上,我试图用填充,填充可变长度输入。
鉴于:
假设变量形状列表是
seq = [[[1,2,3], [4,5,6,7]], [[1], ], [[7,8,9], [10,11]]]
零的固定形状列表的形状为
[3, 2, 4]
fixed_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]]]
输出:
所需的输出是从变量形状列表到其的副本 固定形状列表中的相应尺寸
output = [[[1, 2, 3, 0], [4, 5, 6, 7]], [[1, 0, 0, 0], [0, 0, 0, 0]], [[7, 8, 9, 0], [10, 11, 0, 0]]]
是否有任何递归方式来实现复制过程?
只是一个小小的通知:这只是一个具体的例子,可以有更多其他固定形状,即[3,2,5,6,7]
或[3,4]
用于其他一些序列示例。
编辑:
序列也可以是,
seq = [[1,4,5,7],
[2,8],
[6,3,2]]
expected_output = [[1,4,5,7],
[2,8,0,0],
[6,3,2,0]]
的形状为[3,4]
,填充预计也将在此推广。
编辑:
这是我生成fixed_list
作为对评论的回应的编码。
def _dfs_max_len(seqs: list, layers: defaultdict, count=0):
try:
len_ = len(seqs)
if len_ > layers[count]:
layers[count] = len_
count += 1
except TypeError:
return
for i in range(len_):
_dfs_max_len(seqs[i], layers, count)
def get_seqs_shape(seqs: list):
shape = defaultdict(int)
_dfs_max_len(seqs, shape)
return list(shape.values()) # won't need `list` for python2
def zeros_list(shape: list):
if len(shape) == 1:
return [0 for _ in range(shape[0])]
curnt_shape = shape[0]
sublist = zeros_list(shape[1:])
return [sublist for _ in range(curnt_shape)]
shape = get_seqs_shape(seq)
zeros = zeros_list(shape)
答案 0 :(得分:1)
这是一个半递归解决方案,第一个实际用零填充,第二个嵌入现有的零块(或其他值)。
import itertools as it
def subdims(L):
"""determine the depth and max dimensions of a nested list"""
SL = (subdims(S) for S in L if isinstance(S, list))
return (len(L), *map(max, it.zip_longest(*SL, fillvalue=0)))
def pad(L, dims):
"""zero-pad a nested list to flush faces"""
d, *sdims = dims
L = it.chain(L, it.repeat(0, d-len(L))) if L else it.repeat(0, d)
return list(map(pad, L, it.repeat(sdims)) if sdims else L)
def py_zeros(dims):
"""create an nd block (a nested list) of zeros"""
d, *sdims = dims
return [py_zeros(sdims) if sdims else 0 for _ in range(d)]
def embed(L, Z):
"""copy a nested list into another large enough nested list"""
for i, x in enumerate(L):
if isinstance(x, list):
embed(x, Z[i])
else:
Z[i] = x
演示:
# pad directly or ...
>>> pad(seq, subdims(seq))
[[[1, 2, 3, 0], [4, 5, 6, 7]], [[1, 0, 0, 0], [0, 0, 0, 0]], [[7, 8, 9, 0], [10, 11, 0, 0]]]
>>>
# ... create a block of zeros and ...
>>> py_zeros(subdims(seq))
>>> Z = py_zeros(subdims(seq))
[[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]]]
# ... copy there
>>> embed(seq, Z)
>>> Z
[[[1, 2, 3, 0], [4, 5, 6, 7]], [[1, 0, 0, 0], [0, 0, 0, 0]], [[7, 8, 9, 0], [10, 11, 0, 0]]]
答案 1 :(得分:0)
朴素的非递归解决方案:尝试更新每个索引,中断错误。如果提前知道fixed_list
的形状,则可以避免调用shape
。请注意,这是在fixed_list
上进行的。
seq = [[[1, 2, 3], [4, 5, 6, 7]], [[1]], [[7, 8, 9], [10, 11]]]
fixed_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]],
]
from itertools import product
def shape(xs):
sh = list()
while type(xs) is list:
sh.append(len(xs))
xs = xs[0]
return sh
def upd(template, content):
sh = shape(template)
for ix in product(*map(range, sh)):
temp = template
con = content
for i in ix[:-1]:
try:
temp = temp[i]
con = con[i]
except:
break
else:
temp[: len(con)] = con[:]
upd(fixed_list, seq)