在给定该元素的索引的情况下,更改嵌套列表内部元素的值

时间:2017-12-30 13:01:17

标签: python nested-lists

例如:

  • 我有一个清单

    lst = [1, 2, [4, 6, 7, [11, 13] ], [46, 83], 5]

  • 我有一个指数列表,我们将元素13称为index=[2,3,1](即

    lst[2][3][1]==13))

  • 我怎样才能改变这个值,让13从13开始说是14 输入而不导入任何模块?

如此更新的列表将是[1, 2, [4, 6, 7, [11, 14] ], [46, 83], 5]

但是,解决方案应该是灵活的,因为索引列表会更改该列表中的每个元素。对于某些项目,其长度为3(与元素13类似),但对于某些元素,长度类似于1(如元素2,其索引为index = [1])。

7 个答案:

答案 0 :(得分:3)

你只需要遍历索引列表,直到你到达最后一个。为了简化这个过程,我们可以从最后的索引中分割最后一个索引。

lst = [1, 2, [4, 6, 7, [11, 13] ], [46, 83], 5]
indices = [2, 3, 1]
newval = 14

*head, last = indices
temp = lst
for i in head:
    temp = temp[i]
temp[last] = newval
print(lst)

<强>输出

[1, 2, [4, 6, 7, [11, 14]], [46, 83], 5]

如果您正在运行某些旧版本的Python,则可能需要将该切片分配更改为此效率较低的版本:

head, last = indices[:-1], indices[-1]

答案 1 :(得分:2)

有趣的一个(在我错过了“没有进口”之后,但看到答案的底部部分):

key, reduce(getitem, index, lst)[key] = index.pop(), value

演示:

>>> if 1:
    from operator import getitem
    from functools import reduce

    lst = [1, 2, [4, 6, 7, [11, 13] ], [46, 83], 5]
    index = [2,3,1]
    value = 14
    key, reduce(getitem, index, lst)[key] = index.pop(), value
    print(lst)

[1, 2, [4, 6, 7, [11, 14]], [46, 83], 5]

No-imports版本(仅限Python 2):

key, reduce(list.__getitem__, index, lst)[key] = index.pop(), value

除了愚蠢丑陋的有状态列表理解之外,不能想到Python 3的oneliner ...哦,好吧,也许如果OP是其中一个说“没有进口”的人,当他们真正意味着“没有第三方这些东西“,或者对于那些除了这个细节之外有相同问题的人有用。

答案 2 :(得分:1)

写一个函数。

>>> def list_setter(lst, idxs, val):
...     for i in idxs[:-1]:
...         lst = lst[i]
...     lst[idxs[-1]] = val
>>>
>>> lst = [1, 2, [4, 6, 7, [11, 13] ], [46, 83], 5]
>>> list_setter(lst, [2,3,1], 14)
>>> lst
[1, 2, [4, 6, 7, [11, 14]], [46, 83], 5]
>>> list_setter(lst, [0], 5)
>>> lst
[5, 2, [4, 6, 7, [11, 14]], [46, 83], 5]

根据需要添加错误检查以索引不可能的列表。

答案 3 :(得分:0)

由于您想遍历嵌套列表,因此总是有可能递归:

lst = [1, 2, [4, 6, 7, [11, 13]], [46, 83], 5]
index=[2,3,1]
replace = 14

def rec_replace(lst, index, replace):
    if len(index) == 1:
        lst[index[0]] = replace
        return

    return rec_replace(lst[index[0]], index[1:], replace)

rec_replace(lst, index, replace)

print(lst)

哪个输出:

[1, 2, [4, 6, 7, [11, 14]], [46, 83], 5]

答案 4 :(得分:0)

我不知道这是否合适但是有效,

lst = [1, 2, [4, 6, 7, [11, 13] ], [46, 83], 5]
indices = [2, 3, 1]
newval = 14
indices_str = "".join(["[" + str(i) + "]" for i in indices])
exec_stat = "{}{}={}".format('lst',indices_str, new_val)
exec(exec_stat)

答案 5 :(得分:0)

您可以使用这个较短的递归:

lst = [1, 2, [4, 6, 7, [11, 13] ], [46, 83], 5]
index=[2,3,1]
val = 14
def mutate(lst, current):
   return [(lambda x:val if not all(c == d for c, d in zip(current+[i+1], index)) and len(current+[i]) == len(index) else x)(a) if isinstance(a, int) else mutate(a, current+[i]) for i, a in enumerate(lst)]
print(mutate(lst, []))

输出:

[1, 2, [4, 6, 7, [11, 14]], [46, 83], 5]

答案 6 :(得分:-1)

首先:13的索引是[2, 3, 1],然后你可以这样做:

lst[2][3][1]=14
相关问题