2016-01-29 34 views
3

我在學習Python,來自C#/ Java背景,並且正在玩弄列表行爲。我已經閱讀了一些文檔,但我不明白如何以及爲什麼使用索引大於長度爲1的分片可以附加項目。在Python中追加列表的說明和首選方法

ls = ["a", "b", "c", "d"] 
n = len(ls) # n = 4 

letter = ls[4] # index out of range (list indexes are 0 - 3) 

# the following all do the same thing 

ls += ["echo"] 
ls.append("foxtrot") 
ls[len(ls):] = ["golf"] # equivalent to ls[len(ls): len(ls)] 

print(ls) 

儘管對我來說這似乎很奇怪,但我知道切片如何修改它們操作的列表。我沒有得到的是爲什麼list[len(list)]導致預期的越界誤差,但list[len(list):]沒有。我知道切片與索引有根本的區別,而不是當切片以列表值之外的索引開始時在內部發生的情況。

爲什麼我可以從一個不存在的元素(len(list))開始的列表中返回一個切片?爲什麼這讓我擴大名單?

此外,上述前三種附加項目的方法中,從約定或性能角度來看,哪一項更受歡迎?它們中的任何一個都存在性能劣勢?

+0

我無法解釋當你影響列表拼接時發生了什麼(我甚至不知道爲什麼這是允許的)。首選的形式在python中是最常用的,它可以是'ls + = [「alpha」]或'ls.append(「tango」)'。從性能角度來看,這取決於你的python解釋器。 – DainDwarf

+0

請縮小你的問題;目前尚不清楚它是否是http://stackoverflow.com/q/9490058/3001761或http://stackoverflow.com/q/10623302/3001761或其他內容的重複。你也可以把它看作是改進它的一部分,已經有很多信息了。 – jonrsharpe

+0

注意'ls + ='需要'ls'在本地範圍內(或者在函數中給定'global'聲明),因爲它執行的是分配,但是'ls.append'可以在全局變量上工作,因爲它僅僅是一個方法調用一個現有的可變對象,而不是一個賦值。 「 –

回答

1

雖然a.append(x)a[len(a):] = [x]做同樣的事情,第一個是更清晰,應該幾乎總是被使用。切片更換可能有一個地方,但你不應該找理由去做。如果情況需要的話,應該明確何時做到這一點。

從索引返回列表元素開始,切片返回列表的「子列表」。雖然特定元素存在或不存在,但從數學角度來看,每個列表都有空列表作爲任何兩個相鄰位置之間的「子列表」。考慮

>>> a = [1, 2, 3] 
>>> a[2:2] 
[] 

現在考慮以下順序。在每一步中,我們增加切片

>>> a[0:] # A copy of the list 
[1, 2, 3] 
>>> a[1:] 
[2, 3] 
>>> a[2:] 
[3] 

每一次我們這樣做的起始索引,我們從列表中所產生的片的開頭刪除一個多種元素。那麼當起始索引最終等於最終索引(這隱含地是列表的長度)時會發生什麼?

>>> a[3:] 
[] 

你得到一個空列表,這與以下身份

a + [] = a 
a[:k] + a[k:] = a 

是一致的(第一個是第二個地方k >= len(a)。的特殊情況,現在

,一旦我們看到爲什麼切片存在是有意義的,用另一個列表替換切片意味着什麼?換句話說,如果我們用[1, 2, 3]替換列表[4]的末尾的空列表,我們會得到什麼樣的列表?您得到[1, 2, 3, 4],這符合

[1, 2, 3] + [4] = [1, 2, 3, 4] 

考慮另一個序列,這次涉及片替換。

>>> a = [1,2,3]; a[0:] = ['a']; a 
['a'] 
>>> a = [1,2,3]; a[1:] = ['a']; a 
[1, 'a'] 
>>> a = [1,2,3]; a[2:] = ['a']; a 
[1, 2, 'a'] 
>>> a = [1,2,3]; a[3:] = ['a']; a 
[1, 2, 3, 'a'] 

查看切片替換的另一種方法是將其視爲將列表附加到原始子列表中。當該子列表本身是列表時,則等於追加到原始列表。

+0

很好的解釋。思考片段之間發生的切片(或者元素和列表的末尾)使得操作對我來說是可理解的。 – BrianHVB

0

爲什麼我可以從一個不存在的元素開始列表返回分得一杯羹?

我無法確定,但我的猜測是,這是因爲可以返回一個合理的值(沒有元素指的是,所以返回一個空列表)。

爲什麼這可以讓我擴大名單?

您的切片選擇列表的最後0個元素。然後您將這些元素替換爲另一個列表的元素。

而且,用於附加的項,其中之一是優選的

使用.append()如果要添加單個元素的前三個以上的方法,如果你有內的另一個列表中的元素.extend()

我對性能不太確定,但我的猜測是那些優化非常好。

+0

」您的切片選擇列表中最後的0個元素,然後將這些元素替換爲另一個列表的元素。「我想這是我無法包裹頭部的部分。選擇「無」並將其替換爲「某物」。我明白你可能會選擇最後一個元素,並用[last_elem,new_elem]替換它,但那不是發生了什麼。太可能是元物理。奇怪的行爲,但沒有辦法解決。我只是不喜歡不知道它是如何工作的。 – BrianHVB