如何更改 python 中嵌套列表中的每个元素
How can I change each element in a nested list in python
我一直在从事一个使用大嵌套列表的项目。我不能使用递归函数,因为它们会给我最大递归深度错误。我希望能够浏览列表中的每个项目并根据其类型进行更改。这是我希望该程序执行的操作的简化版本。
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,直到嵌套列表中的每个整数都被除以使得嵌套列表不同。由于递归函数给我错误,还有其他方法吗?
对于嵌套对象来说,这并不是真正的递归方法。此外,最好使用 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]]
为避免递归,您需要实现自己的堆栈。这是一个例子。 (我添加了一个 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]
是包含相关值的直接父列表。
显然,如果在遍历列表的同时修改列表,您需要注意只修改标量值,而不是通过在任何列表对象中添加或删除值来修改其结构。
我一直在从事一个使用大嵌套列表的项目。我不能使用递归函数,因为它们会给我最大递归深度错误。我希望能够浏览列表中的每个项目并根据其类型进行更改。这是我希望该程序执行的操作的简化版本。
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,直到嵌套列表中的每个整数都被除以使得嵌套列表不同。由于递归函数给我错误,还有其他方法吗?
对于嵌套对象来说,这并不是真正的递归方法。此外,最好使用 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]]
为避免递归,您需要实现自己的堆栈。这是一个例子。 (我添加了一个 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]
是包含相关值的直接父列表。
显然,如果在遍历列表的同时修改列表,您需要注意只修改标量值,而不是通过在任何列表对象中添加或删除值来修改其结构。