循环变量和列表中的元素之间的关系是什么?

问题描述:

这里有几个列表:a,b等 我想分别对它们进行一些更改,但我对for循环的行为方式感到困惑。循环变量和列表中的元素之间的关系是什么?

例如: 如果我们做

a, b = range(5), range(5,10) 
for x in [a, b]: x += [0] 
print(a,b) 

我们得到

([0, 1, 2, 3, 4, 0], [5, 6, 7, 8, 9, 0]) 

A,B被修改。

但如果我们这样做

a, b = range(5), range(5,10) 
for x in [a, b]: x = x + [0] 
print(a,b) 

我们得到

([0, 1, 2, 3, 4], [5, 6, 7, 8, 9]) 

A,B不会被修改。 我很困惑,x和a之间的关系是什么?何时或如何修改x的值? 顺便说一句,a + = b和a = a + b有什么区别?

不管怎样,我找到一个解决方案,我们可以做这样的

a, b = range(5), range(5,10) 
lis = [a, b] 
for i, x in enumerate(lis): 
    lis[i] = ... 

那么我们可以修改& B的值。但是这种方法需要额外的列表。

而且有花药解决方案

for x in ['a', 'b']: 
    exec(x + '=' + x + '+ ...') 

而一个简单的解决方案

a, b = range(5), range(5,10) 
for x in [a, b]: x[:] = x + [0] 
print(a,b) 

我们会发现A,B被修改:)

的关系是一样的所有变量绑定在Python中。该名称与该值绑定。你所看到的差异是因为你在做不同的事情,有时候会根据价值进行操作,有时还会根据名称进行操作。

对于列表,+=就地扩展了列表---也就是说,它修改了原始列表。因此,无论使用哪个列表,修改都是可见的。

当您做x = x + [0]时,您将名称x重新命名为新列表(通过添加旧列表加上[0]形成)。这不会修改原始列表,所以使用该列表的其他地方将不会看到更改。

如果你围绕“变量”,“名称”,“值”,“通过引用调用”等方式搜索Python问题,你会发现其他的讨论。 Here是一个在函数参数绑定的上下文中讨论类似问题的问题。原型在for循环变量绑定中是相同的。

+0

看到这个[相关答案](http://stackoverflow.com/a/2022044/1988505)解释更多关于创建一个新的列表,通过添加到它与插入到原始列表。 – 2013-03-12 06:07:48

+0

非常感谢您的回答,现在对我来说更加清晰。看来我应该学习更多关于python的基础知识:) – 2013-03-12 06:32:46

行:

x += something 

改变地方的列表,而:

x = x + something 

通过加入xsomething创建一个全新的列表。

它下面的简单演示没有什么不同:

>>> a = [7]  # The object is [7], name a is connected to it. 
>>> x = a  # Now name x is also connected. 
>>> x += [2]  # Here we change the backing object (behind a AND x). 
>>> a   # So that both names seem to change. 
[7, 2] 
>>> x 
[7, 2] 

>>> a = [7]  # The object is [7], name a is connected to it. 
>>> x = a  # Now name x is also connected. 
>>> x = x + [2] # Here we create a NEW object from the old one, and connect x. 
>>> a   # So a is unchanged. 
[7] 
>>> x   # But x IS changed. 
[7, 2] 

这是我必须要习惯在Python,但事实上,名称和对象名称是指是相当不同的最难的事情,并且通常可以以令人惊讶的方式行事。一旦你坚持下去,它也是它最美丽的特征之一。

我最终刚开始认为名称是C指针,所有对象都在堆上(因为那是我的专长)。可能有更好的方法来思考它,尽管我从来没有为我找到任何。

+0

你是对的,名字和对象是不同的。名字就像*标签*放在一个物体上;通过'name = ...'完成为对象分配标签(这称为将对象绑定到名称)。一个对象可以有很多标签(就像'name2 = name'时一样)。困难在于'name'代表'name = ...'中的一个标签,而'name2 = name'(或'name + = [0]')代表一个* object *。 – EOL 2013-03-12 06:50:28

+0

因此,列表与C中的数组类似,我们可以使用切片来更改值。啊,我找到了另一种解决方案,对于[a,b]中的x:x [:] = x + [0],python是intersting。 – 2013-03-12 06:51:21