2012-03-14 41 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的內容因此不變。