簡體   English   中英

當 Python 語法似乎支持它時,為什么我不能用元組對列表進行切片?

[英]Why can't I slice a list with a tuple, when it seems to be supported by the Python grammar?

我一直在使用官方 Python 站點教程/庫/參考來學習 Python 一段時間。 今天我只是偶然偶然發現了正式的切片參考,並且無法弄清楚為什么沒有人告訴一個可能的場景應該有效,但不幸的是它沒有。

也就是說,根據本文檔,應該可以使用索引和切片的元組從序列中提取 select 元素:

lst = list(range(1, 100, 2))
slc = slice(10, 20, 3)
print( lst[ 1, 5, 8, slc, 30:40:5, 49 ] )

但正如你們中的許多人可能期望的那樣彈出錯誤

回溯(最后一次調用):文件“./slice-test.py”,第 68 行,在 print(lst[ 1, 5, 8, slc, 30:40:5, 49 ] ) 類型錯誤:列表索引必須是整數或切片,而不是元組

這種符號在 Python 中已經存在很長時間了。 至少 Python 2.x 的相同文檔在此處將此術語稱為“擴展切片”

我在這里想念什么? 我可能誤解了這個符號,但我不知道問題在哪里(當然解釋器不支持這一點除外)。

PS我已經在其他地方尋找答案,包括這個問題

PPS 這個問題與索引或 start:end:step 切片本身無關,因此不需要這些示例。

也就是說,根據本文檔,應該可以使用索引和切片的元組從序列中提取 select 元素

該文檔告訴您什么是語法上有效的 Python 代碼,可以將其字節碼編譯成.pyc文件。 沒有告訴你什么是語義上有效的 Python 代碼,它將運行沒有任何錯誤。

語法上無效的代碼只能引發SyntaxError 語言語法僅解釋如何避免這些異常,而不是任何其他異常。

允許使用索引和切片的元組來切片 Python object。 由對象的類型來定義結果會發生什么,或者是否應該發生異常。

Python 對象使用魔術方法__getitem__處理切片(和訂閱)。 在舊版本中,這僅用於訂閱,並且單獨的__getslice__將用於切片。 無論哪種方式,如果[]之間只有一項(即代碼中沒有逗號),則直接傳遞它 - 而不是作為 1 元素元組。 (正如那里所解釋的:所有可能是有效訂閱的東西也是有效的切片;這些被語法讀取為訂閱而不是切片。)每個切片 - 使用特殊切片語法編寫,僅在此切片上下文中有效 - 成為slice object,就像其他任何東西一樣傳遞給__getitem__

我們可以制作自己的 class 來測試它:

>>> class Tester:
...     def __getitem__(self, x):
...         return x
...
>>> t = Tester()
>>> t[0]
0
>>> t['test']
'test'
>>> t[1:2:3]
slice(1, 2, 3)
>>> t[::-1]
slice(None, None, -1)
>>> t[1,2]
(1, 2)
>>> t[(1,2)]
(1, 2)
>>> t[[1,2]]
[1, 2]
>>> t[::-1, ::-1]
(slice(None, None, -1), slice(None, None, -1))
>>> t[1, 5, 8, slice(10, 20, 3), 30:40:5, 49]
(1, 5, 8, slice(10, 20, 3), slice(30, 40, 5), 49)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM