为什么以下两个for
循环的行为超过list
个不同?
在第一个示例中,我有list
int
:修改for
循环中的每个元素并打印结果。但是,值的变化仅在循环范围内。
In [1]: my_list = [1,2,3,4,5,6,7,8,9,10]
In [2]: for e in my_list:
...: e = e*2
...: print e
...:
Out [2]: 2
4
6
8
10
12
14
16
18
20
In [3]: my_list
Out[3]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
在第二个示例中,我有list
list
:修改for
循环中的每个元素并打印结果。 但是,在这种情况下,值的更改将传递到循环范围之外。
In [4]: my_list = [[1,2],[3,4],[5,6],[7,8],[9,10]]
In [5]: for e in my_list:
...: e[0] = e[0] + 1
...: e[1] = e[1] + e[0]
...: print e
...:
Out [5]: [2, 4]
[4, 8]
[6, 12]
[8, 16]
[10, 20]
In [6]: my_list
Out[6]: [[2, 4], [4, 8], [6, 12], [8, 16], [10, 20]]
为什么修改
int
与修改list
条目不同 (因为它也是int
)?
答案 0 :(得分:6)
通过执行e[0] = e[0] + 1
,您实际上正在修改列表e
的第一个元素,即my_list
列表中的第一个列表。您没有将引用修改为列表,my_list
仍然包含相同的列表对象(它只是已更改的这些对象的内容)。
另一方面,执行e = e*2
不会修改e
,它会将e
变量重新分配给新的整数,这是e*2
表达式的结果
为了更清楚,请使用内置id()
功能检查正在发生的事情:
>>> my_list = [1] # shortened for the sake of example
>>> for e in my_list:
... print 'BEFORE id(e)', id(e)
... e = e*2
... print 'AFTER id(e)', id(e)
...
BEFORE id(e) 25364408
AFTER id(e) 25364384
您可以看到变量e
已被重新分配给其他对象。现在,如果你按照你在第二个例子中所做的那样做了:
>>> my_list = [[1,2]]
>>> for e in my_list:
... print 'BEFORE id(e)', id(e)
... e[0] = e[0] + 1
... e[1] = e[1] + e[0]
... print 'AFTER id(e)', id(e)
...
BEFORE id(e) 140680995671144
AFTER id(e) 140680995671144
>>> id(my_list[0])
140680995671144
您看到您一直在使用ID为140680995671144的同一对象上运行,并且my_list
仍然拥有引用到同一个对象,但它是对象的内容改变了。