以下是我从The Python Language Reference复制的切片语法:
slicing ::= primary "[" slice_list "]"
slice_list ::= slice_item ("," slice_item)* [","]
slice_item ::= expression | proper_slice
proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]
lower_bound ::= expression
upper_bound ::= expression
stride ::= expression
根据我的理解,此语法等同于SomeMappingObj[slice_item,slice_item etc...]
,它再次等同于a[0:2:1,4:7:1]
和a =[i for i in range(20)]
。
但是,我无法在IPython中对此进行测试,而且我没有发现任何有关多次切片的问题。我对python中多次切片的解释是否正确?我做错了什么?
In [442]: a=[i for i in range(20)]
In [443]: a[0:12:2]
Out[443]: [0, 2, 4, 6, 8, 10]
In [444]: a[0:12:2,14:17:1]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-444-117395d33bfd> in <module>()
----> 1 a[0:12:2,14:17:1]
TypeError: list indices must be integers or slices, not tuple
答案 0 :(得分:2)
这是有效的语法,因此您没有得到SyntaxError。它只是Python列表上没有意义或支持的操作。同样,"5" + fish
不是SyntaxError,1/0
不是SyntaxError,而I.am.a.monkey
不是SyntaxError。
您不能期望所有语法上有效的表达式都有意义。
答案 1 :(得分:2)
slice_list
应包含与要编入索引的对象一样多的“维度”。我所知道的任何Python库对象都没有使用多维功能,但您可以使用numpy
轻松测试它:
import numpy as np
a = np.array([[1, 2], [3, 4]])
a[0:1, 0]
Python语言中有许多此类功能未直接在主库中使用。 __matmul__
魔术方法(@
运算符)是另一个例子。
答案 2 :(得分:2)
请注意,语法的结构方式允许两件事:
一系列slice
文字:
x:y:z == slice(x, y, z)
x:y == slice(x, y, None)
x: == slice(x, None, None)
x::z == slice(x, None, z)
::z == slice(None, None, z)
:y:z == slice(None, y, z)
:: == slice(None, None, None)
:y: == slice(None, y, None)
还有一些其他模式(x:y:
,:y
等),但每种模式都可以
是上述其中一种的变体。
切片文字只能 在[...]
中使用,而不能在任意表达式中使用。
否则,逗号分隔列表将被视为与任何其他元组一样。当您编写类似f[1, 2:3, 5::7]
的表达式时,f.__getitem__
会收到元组(1, slice(2, 3, None), slice(5, None, 7)
作为其参数。使用该参数f.__getitem__
所做的完全取决于type(f)
__getitem__
的实施。例如,列表和字符串仅接受int
和slice
值作为参数,而dicts只接受可散列值。
答案 3 :(得分:1)
这不是语法问题,因此没有SyntaxError
,完全支持此语法。 list
只是不知道如何处理你的切片。例如,一个虚拟类,它 nothing 但定义__getitem__
接收订阅[]
的内容:
class DummySub:
def __getitem__(self, arg):
print(arg)
f = DummySub()
它只打印arg
。我们可以在语法允许的情况下提供切片,但是,由实现对象来决定这些是否是支持并对其起作用的操作(如nparray
s)或者不(并提出TypeError
):
f[1:2:3, 4:4:4]
(slice(1, 2, 3), slice(4, 4, 4))
的Heck:
f[1:2:3, 4:5:6, 7:8:9, ...] # totally valid
(slice(1, 2, 3), slice(4, 5, 6), slice(7, 8, 9), Ellipsis)
通过在reference for slicings中进一步阅读,您应该看到:
切片的语义如下。使用从切片列表构造的密钥对主数据库进行索引(使用与正常预订相同的
__getitem__()
方法),如下所示。 如果切片列表包含至少一个逗号,则该键是包含切片项转换的元组;否则,单个切片项的转换是关键。
(强调我的)