我一直在做一个使用大的嵌套列表的项目,我不能使用递归函数,因为它们会给我最大的递归深度误差。我不能使用递归函数,因为它们会给我最大的递归深度错误。我希望能够检查列表中的每一个项目,并根据它的类型来改变它。以下是我希望程序所做的简化版本。
list_a = ["string", 1.0, 1.0]
list_b = [1.0, "string", 1.0]
list_c = [list_a, list_b]
def Updater(array):
for elem in array:
if type(elem) == str:
print("string")
if type(elem) == list:
Updater(elem)
if type(elem) == float:
elem /= 2
Updater(list_c)
print(list_c)
我希望它现在将每个整数除以2,直到嵌套列表中的每个整数都被除以2,这样嵌套列表就会有所不同。由于递归函数给我带来了错误,是否有其他方法可以做到这一点?
为了避免递归,你需要实现自己的栈。 下面是一个例子。 (我在这里添加了一个 list_d
包含您的 list_c
和一个标量,以显示叶元素在不同的深度被发现)。)
list_a = ["string", 1.0, 1.0]
list_b = [1.0, "string", 1.0]
list_c = [list_a, list_b]
list_d = [2.0, list_c]
def walk_list(l):
if not l:
return
parent_lists = []
parent_indices = []
current_list = l
current_index = 0
while True:
# descend from current position through lists until
# leaf element or empty list is reached
while True:
val = current_list[current_index]
if not isinstance(val, list):
# found leaf element (result of interest)
yield (val,
parent_lists + [current_list],
parent_indices + [current_index])
break
elif not val:
# found empty list (ignore)
break
else:
# list to descend into
parent_indices.append(current_index)
parent_lists.append(current_list)
current_list = val
current_index = 0
# increment to next position, reascending to parent
# each time we go off the end of any list
while True:
current_index += 1
if current_index < len(current_list):
break
if not parent_lists:
return
current_list = parent_lists.pop()
current_index = parent_indices.pop()
print('Original: ', list_d)
print()
for val, lists, indices in walk_list(list_d):
print("saw value {} at position {}".format(repr(val), indices))
if isinstance(val, float):
lists[-1][indices[-1]] /= 2
print('\nFinal: ', list_d)
给出。
Original: [2.0, [['string', 1.0, 1.0], [1.0, 'string', 1.0]]]
saw value 2.0 at position [0]
saw value 'string' at position [1, 0, 0]
saw value 1.0 at position [1, 0, 1]
saw value 1.0 at position [1, 0, 2]
saw value 1.0 at position [1, 1, 0]
saw value 'string' at position [1, 1, 1]
saw value 1.0 at position [1, 1, 2]
Final: [1.0, [['string', 0.5, 0.5], [0.5, 'string', 0.5]]]
这就是... lists
迭代器返回的是一个越来越深的子列表,这些子列表是在从原始列表到相关元素的路径中遇到的,也就是 lists[0]
将包含原始列表和 lists[-1]
是包含相关值的直接父列表。
显然,如果在迭代列表时修改列表,你需要注意只修改标量值,而不是通过追加或删除任何列表对象的值来修改其结构。
对于嵌套对象来说,并不是一个真正的绕开递归的方法。此外,最好使用 isinstance
. 也就是说,你可以使用
list_a = ["string", 1.0, 1.0]
list_b = [1.0, "string", 1.0]
list_c = [list_a, list_b]
def Updater(lst):
result = []
for item in lst:
if isinstance(item, list):
result.append(Updater(item))
elif isinstance(item, str):
#print(item)
result.append(item)
elif isinstance(item, (float, int)):
result.append(item / 2)
return result
output = Updater(list_c)
print(output)
由此得出
[['string', 0.5, 0.5], [0.5, 'string', 0.5]]