3

有人可以简要解释这两个 Python 操作在修改列表方面的区别吗?

demo = ["a", "b", "c"]

for d in demo:
    d = ""

print demo
#output: ['a', 'b', 'c']

for c in range(len(demo)):
    demo[c] = ""

print demo
#output: ['', '', '']

换句话说,为什么第一次迭代不修改列表?谢谢!

4

3 回答 3

5

循环变量d始终是对可迭代对象元素的引用。这个问题实际上并不是何时或何时不是参考的问题。它与您使用循环执行的分配操作有关。

在第一个示例中,您将对象中元素的原始引用与另一个空字符串的引用重新绑定。这意味着您实际上并没有对value做任何事情。您只需为符号分配一个新的引用。

在第二个示例中,您正在执行索引操作并为该索引处的值分配新引用。demo保持相同的引用,并且您正在替换容器中的值。
该作业实际上相当于:demo.__setitem__(c, "")

a = 'foo'
id(a)  # 4313267976
a = 'bar'
id(a)  # 4313268016

l = ['foo']
id(l)  # 4328132552
l[0] = 'bar'
id(l)  # 4328132552

请注意在第一个示例中,对象 ID 发生了怎样的变化。它是对新对象的引用。在第二个中,我们索引列表并替换容器中的值,但列表仍然是同一个对象。

于 2013-01-01T19:58:51.513 回答
4

在第一个示例中,d可以将变量视为列表中元素的副本。这样做时d = "",您实际上是在修改列表中任何内容的副本,这自然不会更改列表。

在第二个示例中,通过range(len(demo))对列表中的元素进行操作和索引,您可以直接访问和更改列表中的元素。因此,doingdemo[c]会修改列表。

如果您确实想从循环内部直接修改 Python 列表,则可以复制该列表并对其进行操作,或者最好使用列表推导式。

所以:

>>> demo = ["a", "b", "c"]
>>> test = ["" for item in demo]
>>> print test
["", "", ""]

>>> demo2 = [1, 5, 2, 4]
>>> test = [item for item in demo if item > 3]
>>> print test
[5, 4]
于 2013-01-01T19:52:07.793 回答
1

当你这样做时,d = <something>你正在使变量d引用<something>. 这样您就可以d像使用<something>. 但是,如果您这样做d = <something else>,则d现在指向<something else>和不再指向<something>=符号用作赋值运算符)。在 的情况下demo[c] = <something else>,您正在分配<something else>(c+1)th列表中的项目。

但是,要注意的一件事是,如果该项目d具有要调用的自修改方法,则可以执行

for d in demo:
    d.<some method>()

因为列表demo包含那些对象(或对对象的引用,我不记得了),因此如果修改了这些对象,列表也会被修改。

于 2013-01-01T20:18:21.297 回答