这似乎有效:
def stringify(a):
a = a[:] # Make copy of what was passed in.
res = [] # Initialize result list.
my_stack = [] # Initialize our own LIFO stack.
while (a or my_stack): # While a or my_stack is non-empty
if (a):
elem = a.pop(0)
if (not isinstance(elem, list)): # If popped elem is not a list
res.append(str(elem)) # Append stringified elem to res
else:
my_stack.append((a, res)) # Push some stuff, to resume working upon later.
a = elem # Let's start iterating on this inner list
res = [] # This inner list needs a clean res, to start with.
else: # my_stack is non-empty
a, res_prev = my_stack.pop() # Pop some stuff, to resume, work on outer list
res_prev.append(res) # First, append our just-completed inner list.
res = res_prev
return res
Output:
a = [1, [2, [3, 4], 5]]
stringify(a)
['1', ['2', ['3', '4'], '5']]
通过了以下测试用例:
a = [1, [[[2]]]]
a = [[[1]], 2]
a = [1, [[2]]]
a = [1, [2, [3, 4], 5], [6, [7, [8]]], 9]
a = [1, [2, [3, 4], 5]]
a = [1, 2, 3, 4, 5]
关于其工作原理的一些注意事项:
- If the
pop
在我们的名单上a
产生一个整数,我们只需将字符串化的整数附加到res
- If the
pop
在我们的名单上a
生成一个内部列表,我们需要在处理该内部列表之后出现的元素之前开始处理该内部列表。处理完内部列表后,我们必须回到剩余的未弹出元素a
).
- 每当我们检测到当前列表
a
已经变得空虚,我们的res
将指向等效的字符串化列表,现在是我们附加我们的res
无论其(字符串化)外部列表是什么
- 为了处理每个遇到的内部列表,我们采用该内部列表作为新的
a
(分配a = elem
),以及一个空列表作为我们的新列表res
(res = []
)。在此之前,我们需要将当前的内容压入堆栈a
以及我们目前的res
- 为什么是后进先出?好吧,这样看:无论被推动什么last onto
my_stack
表示我们当前正在处理的任何列表的直接外部列表(a
).