2014-02-22 24 views
1

這樣的基礎......抓就地操作

a = [2,3,4,5] 

for x in a: 
    x += 1 

a = [2,3,4,5] 

納達。

,但如果我...

a[2] += 1 
a = [2,3,5,5] 

顯然,我的腦海裏無法理解的基礎知識。 print(x)只返回單元格內的整數,所以它應該簡單地爲每個列表單元格添加一個。什麼是解決方案,我沒有掌握什麼?

+0

要理解/記住的重要一點是'+ ='對於可變對象和不可變對象的作用是不同的。 –

回答

3

要理解什麼是在這裏發生,考慮這兩個代碼段。第一:

for i in range(len(a)): 
    x = a[i] 
    x += 1 

二:

for x in a: 
    x += 1  

這兩個for循環做同樣的事情x。你可以從第一個看到,改變x的值不會改變a;第二個也一樣。

正如其他人指出,列表理解是創造新價值的新列表的好方法:

new_a = [x + 1 for x in a] 

如果你不希望創建一個新的列表,你可以使用下面的模式改變原來的列表:

for i in range(len(a)):  # this gets the basic idea across 
    a[i] += 1 

for i, _ in enumerate(a): # this one uses enumerate() instead of range() 
    a[i] += 1 

for i, x in enumerate(a): # this one is nice for more complex operations 
    a[i] = x + 1 
+0

當你實際上並不需要'range'將完整列表寫入內存時,請使用'xrange'。 – OregonTrail

+0

@OregonTrail,好吧,這取決於你是否使用Python 2或3; Python 3中的'range'就像'xrange'一樣。無論哪種方式,我們的目的語義是相同的。 – senderle

+0

解釋爲什麼這工作只要我用它來追加新的值到列表,而不是實際修改它們。 – Shplody

2

如果你想+1的整數列表的元素:

In [775]: a = [2,3,4,5] 

In [776]: b=[i+1 for i in a] 
    ...: print b 
[3, 4, 5, 6] 

爲什麼for x in a: x += 1失敗?

因爲x不可修改的對象,無法就地修改。如果x是一個可變對象,+=可能的工作:

In [785]: for x in a: 
    ...:  x+=[1,2,3] #here x==[] and "+=" does the same thing as list.extend 

In [786]: a 
Out[786]: [[1, 2, 3], [1, 2, 3]] 
1

在你的循環,你聲明變量x

for x in a 

這是這個變量,你旁邊增加了一個 X + = 1

然後你什麼都不做x。 您應該保存x的地方,如果你想在:)

4

以後使用它在這種情況下,你要定義一個新的變量x,引用的a每個元素反過來。您不能修改x所指的int,因爲int在Python中是不可變的。當您使用+=運營商時,將創建一個新的int,並且x引用此新的int,而不是a中的一個。如果你創建了一個包含intclass,那麼你可以使用你的循環,因爲這個類的實例是可變的。 (這是沒有必要像Python提供做你想做的事的更好的方法)

for x in a: 
    x += 1 

你想要做什麼是基於一個新的列表,並可能將其存儲回。

a = [x + 1 for x in a] 
+0

@senderle你是對的,我注意到在 – OregonTrail

0

時放[2],你reffering到陣列中的第三變​​量「a」 因爲而你的情況是2的第一個元素被存儲在[0]類似地,3在一個[1],4在[2]和5在[3]

1

可變X循環內是每個小區中的一個列表副本。如果您修改x,則不會影響a

一個更「正確」的方式來增加一個列表的每個元素使用列表理解:

a = [elem + 1 for elem in a] 

您也可以使用map功能:

a = map(lambda x: x + 1, a) 
+0

'x'不是每個單元格的副本,它是對不可變類型的引用 – OregonTrail

+0

是的,我的壞。它不是列表中每個對象的副本 – eugecm

2

當你說

for x in a: 
    x += 1 

Python的簡單結合吶我x在每次迭代中的項目從a。因此,在第一次迭代中,x將指代在a的第0個索引中的項目。但是,當你說

x += 1 

它相當於

x = x + 1 

所以,您要添加1〜x的值,使x指新創建的數量(x + 1結果)。這就是爲什麼變更在實際列表中不可見。

爲了解決這個問題,你可以加1,每一個元素這樣

for idx in range(len(a)): 
    a[idx] += 1 

現在,同樣的事情發生,但我們是在指數i新元素替換舊的元素。

輸出

[3, 4, 5, 6] 

注:但我們更喜歡列表理解的方式只要有可能,因爲它留給改變原來的名單,但構建了基於舊列表上一個新的列表。所以,同樣的事情可以這樣

a = [item + 1 for item in a] 
# [3, 4, 5, 6] 

做的主要區別在於,早期我們在更改同一列表現在我們已經創建了一個新的列表,並a指新創建的列表。

+1

如果你想在沒有列表理解的情況下完成這個,這是最好的答案。 – OregonTrail