例如:
我有一个清单
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]
)。
答案 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