如果我有一个数字列表,并且我想使用 for 循环来增加它们,为什么这不起作用:
>>> list=[1,2,3,4,5]
>>> for num in list:
... num=num+1
...
>>> list
[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
我期望得到 [2,3,4,5,6]。
我知道我可以通过这样做来解决这个问题
>>> newlist=[]
>>> for num in list:
... newlist.append(num+1)
...
>>> newlist
[2, 3, 4, 5, 6]
>>>
Run Code Online (Sandbox Code Playgroud)
但一定有更简单的方法。
这是因为您只能获得对列表中变量的引用。当您替换它时,您只需更改该引用所指向的内容,因此列表中的项目保持不变。对此最好的解释是直观地跟踪它- 逐步浏览在该链接中找到的执行可视化,它应该非常清晰。
请注意,可变对象可以就地改变,这将影响列表(因为对象本身将发生变化,而不仅仅是您正在使用的名称所指向的名称)。为了进行比较,请参阅此处的可视化。
这里最好的选择是列表理解。
new_list = [num + 1 for num in old_list]
Run Code Online (Sandbox Code Playgroud)
这是 Python 中赋值工作原理的产物。当你做作业时:
name = something
Run Code Online (Sandbox Code Playgroud)
您正在获取该对象something(这是评估右侧的结果)并将其绑定到name本地命名空间中的名称。当您执行for循环时,您会获取对循环中某个元素的引用,然后通过向旧对象添加 1 来构造一个新对象。然后,您将该新对象分配给当前命名空间中的名称num(一遍又一遍)。
如果原始列表中的对象是可变的,您可以在 for 循环中改变对象:
lst = [[],[],[]]
for sublst in lst:
sublst.append(0)
Run Code Online (Sandbox Code Playgroud)
您将在原始列表中看到这些更改 - 但请注意,我们在这里没有做任何分配。
当然,正如 lattyware 所建议的,您可以使用列表理解来构造一个新列表:
new_list = [x+1 for x in old_list]
Run Code Online (Sandbox Code Playgroud)
你甚至可以让任务就地进行:
old_list[:] = [x+1 for x in old_list]
Run Code Online (Sandbox Code Playgroud)