2017-02-13 47 views
1

在Python可以使用陣列切片表示法以獲得值的子集在一個可迭代:Python:爲什麼[0,1,2] [ - 1:1]不會引發錯誤?

a = [0,1,2] 
a[0:2] 
# returns all members from the 0th to the 2nd: [0,1] 

如果試圖提取的切片,其中第一值是負的,而第二值是正的,然而,該請求返回一個空列表:

a[-1:2] 
# returns [] 

這是違反直覺的我的,作爲該範圍由限定-1:2似乎是一個超集由0所限定的範圍的:2。我知道一個人可以使用負面索引從Python切片符號數組的末尾採摘(例如:a[-1]是2),但它在第一個切片位置看起來像是負值,第二個切片位置應該是負值或者引發一個錯誤,或者返回由第一個位置上的0返回的相同片段的值的超集。

我很想知道切片請求返回的空列表背後的動機,第一個位置爲負值,第二個位置爲正值,如果有人碰巧在這個前面有洞察力...

+3

'a [-1:2]'讀作'a [len(a)-1:2]' – Kos

+0

我聽到了。但是,如果第一個位置的負值所在的切片所返回的值始終爲空,爲什麼語言不會產生錯誤?在切片函數的第一個位置似乎沒有一個負值的合理用例,因此,如果出現這種情況,似乎應該警告開發人員...... – duhaime

+0

@Kos我認爲它更準確地說, 'a [-1:2]'讀作'a [-1%len(a):2]',因爲你可以在那裏放一個-7沒有問題 – Nullman

回答

9

負指數得到最後的元素非常有用:

>>> letters = list('abcdefgh') 
>>> letters[-3:] 
['f', 'g', 'h'] 
>>> letters[-3:-1] 
['f', 'g'] 

這將是一個巨大的錯誤,過早地提高這種情況下的例外。

你也可以混合正,負指數:

>>> letters[-5:6] 
['d', 'e', 'f'] 

這意味着5日最後一個元素之後和第六元素之前的元素。

你的情況:

>>> letters[-1:2] 
[] 

,因爲有過去的,第二個之間沒有元素,則返回一個空列表。

並非總是空的,雖然:

>>> ['a'][-1:2] 
['a'] 
>>> ['a','b'][-1:2] 
['b'] 
+0

啊,你是對的,我沒有想到。我真正的問題是:是否有用於第一個位置爲負片且第二個位置爲正片的用例? – duhaime

+0

這完美地清除它。我現在看到用例 - 謝謝你! – duhaime

3

我認爲這只是一個誤會:負值被解釋爲「從結尾開始計算」,所以[-1:2]不是[0:2]一個超集。這是相反的方式!因爲不管-1是什麼(實際值取決於可迭代的長度),它將始終爲>= 0

在你的情況下,你有一個長度爲3的數組,所以-1被解釋爲2,並且你想得到2到2之間的項目(停止排除),這樣你得到一個空的列表。

2

假設您想要分割最後10個元素。這很容易通過a[-10:]完成。如果這會產生一個錯誤,你會寫一些不愉快的東西,如a[len(a)-10:]。更糟糕的是,如果a不是一個帶有之前使用過的列表的變量,而是您現在計算的某些東西,那麼您需要創建一個新變量,以便有可能縮短這個長度。如果你最後只寫[-10:],你就不會這樣做。

顯然,這可能有缺點,當這不是預期的行爲,但爲了簡潔在其他情況下,這可能是值得的。

相關問題