简体   繁体   English

当 Python 语法似乎支持它时,为什么我不能用元组对列表进行切片?

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

I've been learning Python for awhile using official Python site tutorial/library/reference.我一直在使用官方 Python 站点教程/库/参考来学习 Python 一段时间。 Today I just accidentally stumbled across formal slicing reference and can't figure out why nobody tells about one possible scenario that should work but unfortunately it doesn't.今天我只是偶然偶然发现了正式的切片参考,并且无法弄清楚为什么没有人告诉一个可能的场景应该有效,但不幸的是它没有。

Namely, according tothis document it should be possible to select elements from the sequence using tuple of indexes and slices:也就是说,根据本文档,应该可以使用索引和切片的元组从序列中提取 select 元素:

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

But as many of you might expect error pops-up但正如你们中的许多人可能期望的那样弹出错误

Traceback (most recent call last): File "./slice-test.py", line 68, in print( lst[ 1, 5, 8, slc, 30:40:5, 49 ] ) TypeError: list indices must be integers or slices, not tuple回溯(最后一次调用):文件“./slice-test.py”,第 68 行,在 print(lst[ 1, 5, 8, slc, 30:40:5, 49 ] ) 类型错误:列表索引必须是整数或切片,而不是元组

This notation have been present in Python for a long time.这种符号在 Python 中已经存在很长时间了。 At least the same document for Python 2.x mentions this term as a "extended slicing"here至少 Python 2.x 的相同文档在此处将此术语称为“扩展切片”

What am I missing here?我在这里想念什么? I probably misinterpret this notation but I can't figure out where is the catch(except the fact that this is not supported by interpreter of course).我可能误解了这个符号,但我不知道问题在哪里(当然解释器不支持这一点除外)。

PS I've looked up for an answer elsewhere including this question . PS我已经在其他地方寻找答案,包括这个问题

PPS This question is not about indexing or start:end:step slicing per se, so examples of these are not needed. PPS 这个问题与索引或 start:end:step 切片本身无关,因此不需要这些示例。

Namely, according to this document it should be possible to select elements from the sequence using tuple of indexes and slices也就是说,根据本文档,应该可以使用索引和切片的元组从序列中提取 select 元素

The document tells you about what is syntactically valid Python code, that can be bytecode-compiled into a .pyc file.该文档告诉您什么是语法上有效的 Python 代码,可以将其字节码编译成.pyc文件。 It does not tell you about what is semantically valid Python code, that will run without any errors.没有告诉你什么是语义上有效的 Python 代码,它将运行没有任何错误。

Only SyntaxError can be raised by syntactically invalid code.语法上无效的代码只能引发SyntaxError The language grammar only explains how to avoid those exceptions, not any others.语言语法仅解释如何避免这些异常,而不是任何其他异常。

It is allowed to use a tuple of indexes and slices to slice a Python object.允许使用索引和切片的元组来切片 Python object。 It is up to the object's type to define what happens as a result, or if an exception should occur instead.由对象的类型来定义结果会发生什么,或者是否应该发生异常。

Python objects handle slicing (and subscription) using the magic method __getitem__ . Python 对象使用魔术方法__getitem__处理切片(和订阅)。 In older versions, this was only for subscription, and a separate __getslice__ would be used for slicing.在旧版本中,这仅用于订阅,并且单独的__getslice__将用于切片。 Either way, if there is only one item between the [] (ie, no commas in the code), it is passed directly - not as a 1-element tuple.无论哪种方式,如果[]之间只有一项(即代码中没有逗号),则直接传递它 - 而不是作为 1 元素元组。 (As explained there: everything that would be a valid subscription is also a valid slicing; these are read by the grammar as subscriptions instead of slicings.) Each slice - written using the special slice syntax, only valid in this slicing context - becomes a slice object, which is passed to __getitem__ just like anything else. (正如那里所解释的:所有可能是有效订阅的东西也是有效的切片;这些被语法读取为订阅而不是切片。)每个切片 - 使用特殊切片语法编写,仅在此切片上下文中有效 - 成为slice object,就像其他任何东西一样传递给__getitem__

We can make our own class to test it:我们可以制作自己的 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.

相关问题 为什么我不能在Python中使用'+'运算符将列表添加到列表中? - Why can't I add a tuple to a list with the '+' operator in Python? 为什么我可以在python中更新列表切片但不更新字符串切片? - Why can I update a list slice but not a string slice in python? 为什么我不能在Python中加入该元组? - Why can't I join this tuple in Python? 如果 Python 切片复制引用,为什么我不能用它来修改原始列表? - If Python slice copy the reference, why can't I use it to modify the original list? 尝试在使用for的列表中查找元组时,为什么会出现“无法分配给运算符”错误? - Why do I get a “Can't assign to operator” error when trying to find tuple in a list using for? 为什么我不能从列表中打印单个元组? - why can't I print a single tuple from a list? 为什么在创建嵌套对象列表时Python崩溃? - Why seems Python to crash when I create a nested list of objects? Python:为什么我不能将元组解压缩到字典中? - Python: Why can't I unpack a tuple into a dictionary? 为什么我不能在python3中子类化元组? - Why can't I subclass tuple in python3? 为什么我不能在 Python lambda 中使用元组打包? - Why can't I use tuple packing in a Python lambda?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM