for循环中的分配需要显式索引吗?

时间:2019-04-18 08:45:48

标签: python

TL; DR:是否可以使用for循环重写这种类型的循环而无需显式索引?

vals = [0, 1]
for i, _ in enumerate(vals):
    vals[i] += 1

并仍按预期工作,即增加vals的元素吗?


我知道这不会增加vals

vals = [0, 1]
for v in vals:
    v += 1

如果我想使用for循环,那么我是否会坚持使用显式索引?

4 个答案:

答案 0 :(得分:3)

您的vals列表需要包含可变对象。但是,由于整数是不可变的,因此v += 1永远不会使值突变,并且始终将局部变量v替换为新值,这不会反映到列表中。您将始终必须明确替换列表中的值。您不需要enumerate来提供多余的第二个值:

for i in range(len(vals)):
    vals[i] += 1

但是针对这种特定情况的真正的pythonic解决方案会简单得多:

vals = [i + 1 for i in vals]

答案 1 :(得分:1)

这等同于:

vals = [i + 1 for i in vals]

但是如果您想使用enumerate,这很愚蠢,但是:

vals = [vals[i]+1 for i, _ in enumerate(vals)] 

答案 2 :(得分:1)

如果您的唯一目标是避免立即拆包,则可以

vals = [0, 1]
for item in enumerate(vals):
    vals[item[0]] += 1

由于不需要原始值,因此也可以

vals = [0, 1]
for i in range(len(vals)):
    vals[i] += 1

最后,就像@deceze指出的那样,您可以通过编写类似的理解来将整个列表替换为新列表

vals = [0, 1]
vals = [i + 1 for i in vals]

所有这些示例都避免了循环中的多个分配。请记住,理解力将完全取代您的列表。如果程序的其他任何部分都依赖原始文件,则不会自动更新。

问题在于整数是不可变的,因此+= 1实际上创建了一个新的整数并将其分配给列表。如果要保留原始列表引用,则必须进行显式索引。

答案 3 :(得分:-1)

You can read about exactly why this doesn't work like you think it does in the Python reference

但是,要做您想做的事情,我认为列表理解是一种不错的,简洁的Python方式。例如:

new_values = [(x + 6) for x in your_list]