2017-10-19 79 views
1

我正在寻找一个更好的解决方案,用于更改未知和变化深度的嵌套列表中的特定项目。动态更改Python中未知深度的嵌套列表中的特定项目

说,我有一个清单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')会做伎俩。

但是......坦率地说......我对这个解决方案并不满意,必须有一种更流畅的Python方法来实现这一点。我可能错过了一些东西。

任何人都可以想到更动态的方式,我不必预先定义可能级别的最大数量?

编辑:

在上面的例子中,我得到了我想要改变,这使得该方法列表中的指数似乎有点过于复杂。但是,在我的具体情况中,我实际上需要使用某个项目的索引来更改另一个具有相同结构的列表中的另一个项目。

所以我必须坚持使用索引列表。

+0

有,它利用'递归'。谷歌搜索它会让你远远,因为你的情况是一个非常典型的例子。 –

回答

1

真的相信你的功能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) 
+0

的确如此,当我发现它时我可以改变它。但是,我恐怕忘了提及,使用特定项目的索引是至关重要的。因为那样我可以在同一个结构的另一个列表中的相同位置上更换一个项目,这非常方便...因此,您的答案非常好,谢谢。 – user1111111

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']]]] 

这是一个有点特殊的你的情况,但它的工作原理。

+0

不幸的是,我忘了提及,使用索引非常重要,这样您就可以在同一个结构的不同列表中的项目的确切位置上更改项目。但除此之外,这绝对是一个非常好的解决方案。 – user1111111