2012-03-14 36 views
25

可能重复:
Python: How do I pass a variable by reference?Python:什么时候通过引用传递变量,何时传值?

我的代码:

locs = [ [1], [2] ] 
for loc in locs: 
    loc = [] 

print locs 
# prints => [ [1], [2] ] 

为什么是locs元素loc没有参考?

Python:除非明确复制,否则一切都作为参考传递[这是不是真的? ]

请解释.. python如何决定引用和复制

更新:

怎么办?

def compute(ob): 
    if isinstance(ob,list): return process_list(ob) 
    if isinstance(ob,dict): return process_dict(ob) 

for loc in locs: 
    loc = compute(loc) # What to change here to make loc a reference of actual locs iteration ? 
  • LOCS必须包含最终的处理响应!我不想使用enumerate,没有它可能吗?
+4

一切都按价值传递,但每个值都只是一个参考;) – wim 2012-03-14 05:42:27

回答

17

Python中的所有内容都是按值传递和分配的,这与所有内容都按Java中的值传递和分配的方式相同。 Python中的每个值都是一个对象的引用(指针)。对象不能是值。赋值总是复制值(这是一个指针);两个这样的指针可以指向同一个对象。对象从不复制,除非你明确地做了某些事情来复制它们。

对于您的情况,循环的每次迭代都将列表元素分配给变量loc。然后,您将其他分配给变量loc。所有这些值都是指针;你正在分配指针;但是您不会以任何方式影响任何对象。

+0

以我的观点来看 - 你说它是最好的。 只要告诉我更新问题的答案 - 你错过了那部分。 – 2012-03-15 05:40:30

+0

那么整数和浮点数会发生什么呢?他们只是被认为是不可变的对象吗? python如何管理它,因为我确信它无法在内存中保存所有可以被引用的数字。 – 2017-04-23 23:55:41

+0

@AndrewS:整数和浮点数确实是不可变的(应该很明显,他们没有方法可以改变它们自己)。我不确定你评论的第二部分意味着什么。 – newacct 2017-04-28 20:20:27

2

一切都通过对象传递。重新绑定和变异是不同的操作。

locs = [ [1], [2] ] 
for loc in locs: 
    del loc[:] 

print locs 
3

当你说

loc = [] 

你重新绑定loc变量

也许你想

loc[:] = [] 

新创建的空列表,它分配一个切片(恰巧成为整个列表)的loc到空列表

+1

我相信这最后一个例子是OP正在寻找的! – 2013-05-24 08:45:45

7

它不能帮助Python在参考或值的方面进行思考。两者都不正确。

在Python中,变量只是名称。在for循环中,loc只是一个指向列表中当前元素的名称。做loc = []只需重新绑定名称loc到一个不同的列表,只留下原始版本。

但因为在你的榜样,每一个元素是一个列表,你实际上可以发生变异这个元素,这将在原来的列表中体现出来:

for loc in locs: 
    loc[0] = loc[0] * 2 
+2

阅读* Idiomatic Python * - [“其他语言有变量,Python有标签。”](http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other语言 - 有变量)其余的也是很好的阅读。 ;) – 2012-03-14 05:50:09

+0

如何修改容器的每个元素? \ – 2012-03-14 05:54:43

+0

@Yugal我上面写的部分内容不清楚? – 2012-03-14 05:56:24

44

Effbot(又名弗雷德里克Lundh开发)描述了Python的变量传递风格作为逐个对象:http://effbot.org/zone/call-by-object.htm

对象分配在堆上,指向它们的指针可以在任何地方传递。

  • 当你进行分配,如x = 1000,字典项创建,在当前的命名空间中的字符串“X”映射到一个指向包含一个千整数对象。
  • 当您使用x = 2000更新“x”时,会创建一个新的整数对象并更新字典以指向新对象。旧的一千个对象是不变的(并且根据其他事物是否指向该对象,可能还可能不存在)。
  • 当您执行新的作业(如y = x)时,会创建一个新的词典条目“y”,指向与“x”条目相同的对象。
  • 像字符串和整数的对象是不可变的。这只是意味着没有方法可以在创建对象后更改对象。例如,一旦创建了一千个整数对象,它将永远不会改变。数学是通过创建新的整数对象完成的。
  • 像列表这样的对象是mutable。这意味着对象的内容可以通过指向对象的任何东西来改变。例如,x = []; y = x; x.append(10); print y将打印[10]。空的列表已创建。 “x”和“y”都指向相同的列表。 附加方法突变(更新)列表对象(就像向数据库添加记录一样),并且结果对“x”和“y”都是可见的(就像数据库更新对每个到数据库的连接都是可见的一样)。

希望能够为您澄清问题。

+1

优秀的答案。 – sunqiang 2012-03-14 13:57:53

2

为什么loc没有引用loc元素?

它是。或者至少,Python的每一个变量都是这样的。 Python变量是名称,而不是存储loc是用于指代[[1,2], [3,4]]的元素的名称,而locs是指引用整个结构的名称。

loc = [] 

并不意味着“看东西loc的名字,并使它变成[]”。它不能的意思是,因为Python对象是没有能力这样的东西。

相反,它的意思是“导致loc停止成为它当前名称的名称,并且开始替代名称为[]”。 (当然,这意味着在那里提供的具体的[],因为通常在存储器中可能有几个对象是相同的。)

当然,locs的内容因此不变。