我有一个嵌套列表:
x=[[[0, 1, 2], [0, 1, 2]], [[0, 1], [0, 1, 2]], [[0]], [[0, 1], [0, 1, 2, 3, 4]]]
现在,目标是获得具有相同结构但其元素被其“全局”计数数字替换的嵌套列表。因此,所需的输出应如下所示:
y=[[[0, 1, 2], [3, 4, 5]], [[6, 7], [8, 9, 10]], [[11]], [[12, 13], [14, 15, 16, 17, 18]]]
我与它战斗了最后几个小时,但没有成功。
理想情况下,我希望有一个通用的解决方案,能够处理任意深度的嵌套。
任何帮助将不胜感激。预先谢谢你!
答案 0 :(得分:3)
这是一个递归解决方案,该解决方案就地进行替换并依赖于要替换的元素的type
。这个想法是跟踪“全局计数器”并将其传递给递归调用,以便它知道用以下内容替换元素:
x = [[[0, 1, 2], [0, 1, 2]], [[0, 1], [0, 1, 2]], [[0]], [[0, 1], [0, 1, 2, 3, 4]]]
def replace(lst, i):
for j in range(len(lst)):
if isinstance(lst[j], list):
lst[j], i = replace(lst[j], i)
else:
lst[j] = i
i += 1
return lst, i - 1
replace(x, 0)
print(x)
# [[[0, 1, 2], [3, 4, 5]], [[6, 7], [8, 9, 10]], [[11]], [[12, 13], [14, 15, 16, 17, 18]]]
答案 1 :(得分:2)
这是另一个递归解决方案。它使用itertools.count
并建立一个新列表。就个人而言,我希望尽可能避免整数索引。
from itertools import count
def structured_enumerate(lst, counter=None):
'enumerate elements in nested list, preserve structure'
result = []
if counter is None:
counter = count()
for x in lst:
if isinstance(x, list):
result.append(structured_enumerate(x, counter))
else:
result.append(next(counter))
return result
演示:
>>> x = [[[0, 1, 2], [0, 1, 2]], [[0, 1], [0, 1, 2]], [[0]], [[0, 1], [0, 1, 2, 3, 4]]]
>>> structured_enumerate(x)
[[[0, 1, 2], [3, 4, 5]],
[[6, 7], [8, 9, 10]],
[[11]],
[[12, 13], [14, 15, 16, 17, 18]]]
〜编辑〜
这是尝试与任何可迭代,可索引或不可索引的通用解决方案的尝试,您可以在其中指定要从迭代中排除的可迭代类型。
from itertools import count
def structured_enumerate(iterable, dontiter=(str,), counter=None):
'enumerate elements in nested iterable, preserve structure'
result = []
if counter is None:
counter = count()
for x in iterable:
# check if x should be iterated
try:
iter(x)
is_iterable = True
except TypeError:
is_iterable = False
# strings of length zero and one are a special case
if isinstance(x, str) and len(x) < 2:
is_iterable = False
if is_iterable and not isinstance(x, dontiter):
subresult = structured_enumerate(x, dontiter, counter)
result.append(subresult)
else:
result.append(next(counter))
return result
演示:
>>> fuzzy = [{0, 0}, '000', [0, [0, 0]], (0,0), 0]
>>> structured_enumerate(fuzzy)
[[0, 1], 2, [3, [4, 5]], [6, 7], 8]
>>> structured_enumerate(fuzzy, dontiter=())
[[0, 1], [2, 3, 4], [5, [6, 7]], [8, 9], 10]
>>> structured_enumerate(fuzzy, dontiter=(tuple, set))
[0, [1, 2, 3], [4, [5, 6]], 7, 8]