Python的扩展切片表示法的形式语法?

Evg*_*eev 2 python syntax slice

例如,Numpy允许多维切片:

a[:, 0, 7:9]
Run Code Online (Sandbox Code Playgroud)

这提出了一个问题:还有什么可能吗?(想象一下可能性!)

根据此答案和一些试验(见下文),如果有一个逗号,Python的构建物,其中的一些可以是切片对象的元组,并且(作为传递key)到__getitem__(self, key)a.

文档__getitem__(..)未指定此行为.有没有我错过的官方文件?特别是,这种语法如何向后兼容?(在网上搜索"python扩展切片表示法"给出了"Python 2.3中的新功能",但没有提到它.)


实验

>>> class Test(object):
...     def __getitem__(self, x):
...         print repr(x)


>>> t = Test()
Run Code Online (Sandbox Code Playgroud)

首先,Python发现可以识别多切片的东西:

>>> t[1]
1

>>> t['a':,]
(slice('a', None, None),)

>>> t['a':7:('b','c'),]
(slice('a', 7, ('b', 'c')),)

# Seems like it can be arbitrary objects?
>>> t[(t,t):[4,5]]
slice((<__main__.Test object at 0x07D04950>, <__main__.Test object at 0x07D04950>), [4, 5], None)

>>> t[::]
slice(None, None, None)

>>> t[:]
slice(None, None, None)

>>> t[::,1,::,::,:,:,:]
(slice(None, None, None), 1, slice(None, None, None), slice(None, None, None), slice(None, None, None),  slice(None, None, None), slice(None, None, None))

>>> t[...]
Ellipsis

>>> t[... , ...]
(Ellipsis, Ellipsis)

>>> t[  .   .      .    ]
Ellipsis
Run Code Online (Sandbox Code Playgroud)

一些不允许的事情(SyntaxError):

# Semicolon delimiter
t['a':5; 'b':7:-7]
# Slice within a slice
t['a':7:(9:5),]
# Two trailing commas
t[5,,]
# Isolated comma
t[,]
# Leading comma
t[,5]
# Empty string
t[]
# Triple colon
t[:::]
# Ellipses as part of a slice
t[1:...]
t[1:2:...]
# Ellipses inside no-op parens:
t[(...)]
# Any non-zero and non-three number of dots:
t[.]
t[..]
t[ .  .  .  . ]
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 5

一切皆有可能,只要它是一个有效的Python表达式.由表达式之间生成的对象[...]传递给__getitem__方法.而已.

逗号产生一个元组,:一个表达式中的冒号产生一个slice()对象.除此之外,使用你想要的任何东西.

那是因为语法允许任何expression_list符号.请参阅参考文档:

subscription ::=  primary "[" expression_list "]"
Run Code Online (Sandbox Code Playgroud)

切片在进一步指定Slicings部分:

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
Run Code Online (Sandbox Code Playgroud)

因此,expression允许任意s,并:触发proper_slice语法规则.

请注意lower_bound,upper_boundstride表达式结果用于构造一个slice()只能处理整数值的对象.任何无法转换为整数的东西都会导致TypeError被引发.这与语法错误不同; t[1:...]语法上很好,但...不能转换为整数,因此你得到一个运行时TypeError异常.使用非整数切片值的两个示例在Python版本2.4及更低版本上是不可能的.

您的实际语法错误都源于无效表达式.除了: proper_slice符号之外,如果你不能把它[...]放在任务的右边,你也不能在一个切片中使用它.

例如,;只能用于在单个逻辑行上放置多个简单语句.语句可以包含表达式,但表达式永远不能包含语句,不包括;表达式.(9:5),不是一个有效的表达式(在Python中没有其他地方你可以:在括号中使用,parenth_form规则不允许任何这样的选项).

用于切片Python 2语法稍微复杂一点,那...就是语法中的特定符号,你实际上不能使用...切片的外部(在Python 3中你可以...在表达式有效的任何地方使用),这就是为什么t[(...)]是Python 2中的语法错误,但Python 3中没有.