2014-09-23 28 views
1

我試圖用Python來完成某些工作,但在互聯網上找不到有關這方面的信息,所以這裏是我的問題。如何在不復制對象的情況下將var添加到Python列表中?

有了這個示例代碼:

a = 5 
b = [a] 

我需要B [0]是一個指針引用一個。目前如果我做

b[0] = 7 

a.var仍然是5,如果我將值設置爲b [0],a保持不變。

我想知道是否有任何方式在Python中存儲一個數組中的對象而不復制這個,所以如果我修改一個我也修改另一個。

編輯一個

我想澄清一個好一點什麼,我試圖完成的,所以也許我能找到真正的答案。

我有一個像

class Foo(object): 
    def __init__(self): 
     self.var = 7 

自定義類我也有像這樣的列表:

myList = [Foo()] 

我真正的問題是在這裏:

在一些地方的代碼,我需要做以下任務:

self.foo = myList[0] 

然後,當我嘗試訪問此foo var時,我注意到這從來沒有從原始實例更新。所以基本上這就是我需要的。

編輯兩個

所有的答案是正確的。在我的任務的每一步中使用id(var)我都可以驗證Object始終是相同的,所以錯誤必須在其他地方。感謝所有人的幫助,我希望這篇文章可以幫助未來的其他人。

+0

對不起,整數是不可變的。當'a'引用一個int時,修改它的唯一方法就是執行'a = some_other_value'。 – Kevin 2014-09-23 19:22:42

+1

在Python中,賦值永遠不會複製對象;變量都是引用,並且賦值重新引用引用。查看[Python執行模型](https://docs.python.org/2/reference/executionmodel.html)和[從C++角度看Python變量名的語義](http://rg03.wordpress.com/2007/04/21 /語義的-蟒-可變名稱-從-AC-透視/)。 – user2357112 2014-09-23 19:23:27

+0

這只是一個例子,我實際上需要一個OBJECT而不是一個整數 – 2014-09-23 19:23:28

回答

3

您是否可以這樣做取決於您的列表元素是否爲immutable or mutable types。不可變的類型不能改變,所以當你重新分配一個不可變的變量時,它實際上是創建一個新的對象並用相同的標籤來標記它。可變類型可以更改,因此可以更改基礎對象而不必重新分配它。

例如,說a是一個列表,這是一個可變類型。

a = [5] 
b = [a] 
a[0] = 3 
print(b) 
# [[3]] 

a.append('hi') 
print(b) 
# [[3, 'hi']] 

您的測試代碼實際上按照您想要的方式工作,因爲objects are mutable

class Object(): 
    pass 

a = Object() 
a.var = 5 

b = [a] 
b[0].var = 7 

print(a.var) 
# 7 

由於所有相同的原因,您的其他示例代碼仍然可以正常工作。當我分配a = l[0]時,它不會複製任何內容,它只是爲l[0]引用的對象創建附加引用a

l = [Object() for _ in range(5)] 
l[0].var = 5 

a = l[0] 
l[0].var = 7 

print(a.var) 
# 7 
+0

打印ID我看到對象完全一樣,所以我發現沒有更新的錯誤應該在別的地方。我會將你的答案標記爲正確的,因爲如果問題確實是最接近我的問題的答案。感謝您的幫助 – 2014-09-23 19:40:05

5

你已經被存儲的對象,即整數5.你所不存儲的名稱是值的名稱a和值5之間的結合。您的問題是,操作b[0] = 7不會修改對象5;它只修改b[0]和它的值(從5到7)之間的綁定,而保留值本身(5和7)不變。事實上,你不能修改值5,因爲5是一個整數,Python中的整數是不可變的。

另一種說法是,b[0] = 7不修改b[0]引用的對象;相反,它會修改b所提及的對象。 b是一個列表,列表是內部跟蹤其索引指向哪些對象的對象。當你做b[0] = 7時,這告訴b「讓你的0索引指向這個新對象」。它不會「通知」5(舊值)或7(新值),它們現在由b[0]指向。 Python中的對象不知道什麼類型的引用指向它們;他們只知道他們指的是什麼(如果有的話)。

你所要求的不是一種存儲對象的方法,而是存儲一個「變量」 - 也就是說,本地名稱空間中的名稱與值之間的綁定。答案是,通常情況下,沒有辦法在Python中執行此操作。沒有任何構造可以讓你做b = something(a),這樣當你以後做b[0] = 8時,a會改變。

如果您想要修改名稱 - 值綁定,您需要更改a,方法是將其內容更改爲某種類型的對象,而不僅僅是將其設置爲普通變量。例如,如果你這樣做:

a = [5] 
b = a 
b[0] = 7 

然後你會發現a也發生了變化。對於其他類型的對象也是如此:如果將a設置爲某些其他類型的屬性可以更改的對象,然後您就地更改其屬性,則不管您如何引用目的。

您可能會發現閱讀Python變量的工作方式很有幫助,例如在this articlethis one中。

+0

在對OP進行編輯之後,我不認爲他所要求的是「變量」解釋。 – 2014-09-23 19:36:01

1

你寫

a = 5

b = [a]

我需要B [0]是一個指針引用一個。

你不行。您可以a指向一個可變對象,改變價值爲該對象:

class Object(object): 
    '''an object''' 

a = Object() 
a.value = 5 
b = a 
b.value = 7 

現在a.value回報:

7 

類似的,但有一個列表這個時候:

a = [5] 
b = a 
b[0] = 7 

現在a[0]是:

7 
相關問題