我正在寻找一个更好的解决方案来更改未知和不同深度的嵌套列表中的特定项目。
说,我有一个列表lst = ['a', 'b', [['c'], ['d', ['e', 'f']]]
,我想将'e'
更改为'x'
。
我可以通过简单的硬编码来做到这一点:
lst[2][1][1][0] = 'x'
但是我必须使用未知数量的索引来改变不同的项目。例如,更改'c'
只需要3个索引。
为了使它更有活力,我已经编写了一个函数来返回某个项目的所需索引,在这种情况下indices = get_indices('e', lst)
会返回列表[2, 1, 1, 0]
所以我目前的解决方案是以下功能:
def set_element(lst, index, value):
levels = len(index)
if levels == 1:
lst[index[0]] = value
elif levels == 2:
lst[index[0]][index[1]] = value
elif levels == 3:
lst[index[0]][index[1]][index[2]] = value
elif levels == 4:
lst[index[0]][index[1]][index[2]][index[3]] = value
elif levels == 5:
lst[index[0]][index[1]][index[2]][index[3]][index[4]] = value
elif levels == 6:
lst[index[0]][index[1]][index[2]][index[3]][index[4]][index[5]] = value
else:
return False
return True
调用set_element(lst, indices, 'x')
可以解决问题。
但是......坦率地说......我对这个解决方案不太满意,必须有一种更顺畅,更加方便的方法来实现这一目标。我可能错过了一些东西。
任何人都可以想到一个更加动态的方式,我不必预先定义可能的最大数量吗?
修改
在上面的例子中,我从列表中得到了我想改变的索引,这使得该方法看起来有点过于复杂。但是,在我的具体情况下,我实际上需要使用项目的索引来更改同一结构的不同列表中的另一个项目。
所以我必须坚持使用索引列表。
答案 0 :(得分:2)
我真的相信你的函数get_indices
几乎已经解决了你的问题 - 就在你找到元素时 - 改变它! =)
但作为答案 - 使用递归(正如您在find_indices中使用的那样)
def set_element(lst, index, value):
if(len(index)==1):
lst[index[0]] = value
else:
set_element(lst[index[0]],index[1:],value)
答案 1 :(得分:1)
这个怎么样:
lst = ['a', 'b', [['c'], ['d', ['e', 'f']]]]
def change(seq, what, make):
for i, item in enumerate(seq):
if item == what:
seq[i] = make
elif type(item) == list:
change(item, what, make)
return lst
print(change(lst, 'c', 'k'))
#['a', 'b', [['k'], ['d', ['e', 'f']]]]
它对您的案例有点具体,但它确实有效。