[英]substitute elements in the nested list by their counting numbers
I have a nested list: 我有一个嵌套列表:
x=[[[0, 1, 2], [0, 1, 2]], [[0, 1], [0, 1, 2]], [[0]], [[0, 1], [0, 1, 2, 3, 4]]]
Now, the goal is to get a nested list with the same structure but with elements replaced by their "global" counting numbers. 现在,目标是获得具有相同结构但元素被其“全局”计数数字替换的嵌套列表。 So, the desired output should look like this:
因此,所需的输出应如下所示:
y=[[[0, 1, 2], [3, 4, 5]], [[6, 7], [8, 9, 10]], [[11]], [[12, 13], [14, 15, 16, 17, 18]]]
I fight with it for the last couple of hours but without success. 我在最后几个小时内与之抗争,但没有成功。
Ideally, I'd like to have a universal solution being able to work with an arbitrary depth of nesting. 理想情况下,我希望有一个通用的解决方案,能够处理任意深度的嵌套。
Any help would be very much appreciated. 任何帮助将不胜感激。 Thank you in advance!
先感谢您!
Here's a recursive solution that does the replacement in-place and relies on the type
of the element being replaced. 这是一个递归解决方案,它就地进行替换并依赖于要替换的元素的
type
。 The idea is to keep track of the "global counter" and pass it into the recursive calls so that it knows what to replace elements with: 这个想法是跟踪“全局计数器”并将其传递给递归调用,以便它知道用以下内容替换元素:
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]]]
Here's another recursive solution. 这是另一个递归解决方案。 It uses
itertools.count
and builds a new list. 它使用
itertools.count
并构建一个新列表。 Personally, I like to avoid integer indexing when possible for readability. 就个人而言,我希望尽可能避免整数索引以提高可读性。
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
Demo: 演示:
>>> 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]]]
~edit~ 〜编辑〜
Here's an attempt at a generic solution that works with any iterable, indexable or not, where you can specifiy iterable types to exclude from iteration. 这是一种尝试与任何可迭代,可索引或不可索引的通用解决方案的尝试,您可以在其中指定可迭代类型以将其排除在迭代之外。
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
Demo: 演示:
>>> 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]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.