如何在Python中使用省略号切片语法?

问题:如何在Python中使用省略号切片语法?

这是Python的“隐藏”功能中提到 ,但是我看不到很好的文档或说明该功能如何工作的示例。

This came up in Hidden features of Python, but I can’t see good documentation or examples that explain how the feature works.


回答 0

Ellipsis,或者...不是隐藏功能,它只是一个常量。例如,它与JavaScript ES6完全不同,后者是语言语法的一部分。没有内置的类或Python语言构造函数使用它。

因此,它的语法完全取决于您或其他人是否具有编写代码来理解它。

Numpy使用它,如文档中所述。这里有一些例子。

在您自己的Class中,您将像这样使用它:

>>> class TestEllipsis(object):
...     def __getitem__(self, item):
...         if item is Ellipsis:
...             return "Returning all items"
...         else:
...             return "return %r items" % item
... 
>>> x = TestEllipsis()
>>> print x[2]
return 2 items
>>> print x[...]
Returning all items

当然,这里有python文档语言参考。但是这些不是很有帮助。

Ellipsis, or ... is not a hidden feature, it’s just a constant. It’s quite different to, say, javascript ES6 where it’s a part of the language syntax. No builtin class or Python language constuct makes use of it.

So the syntax for it depends entirely on you, or someone else, having written code to understand it.

Numpy uses it, as stated in the documentation. Some examples here.

In your own class, you’d use it like this:

>>> class TestEllipsis(object):
...     def __getitem__(self, item):
...         if item is Ellipsis:
...             return "Returning all items"
...         else:
...             return "return %r items" % item
... 
>>> x = TestEllipsis()
>>> print x[2]
return 2 items
>>> print x[...]
Returning all items

Of course, there is the python documentation, and language reference. But those aren’t very helpful.


回答 1

省略号用在numpy中,以分割高维数据结构。

它的目的是在这一点上插入尽可能多的完整切片(:),以将多维切片扩展到所有维度

范例

>>> from numpy import arange
>>> a = arange(16).reshape(2,2,2,2)

现在,您有了一个2x2x2x2阶的4维矩阵。要选择第4维的所有第一个元素,可以使用省略号

>>> a[..., 0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

相当于

>>> a[:,:,:,0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

在您自己的实现中,您可以随意忽略上述合同并将其用于您认为合适的任何事情。

The ellipsis is used in numpy to slice higher-dimensional data structures.

It’s designed to mean at this point, insert as many full slices (:) to extend the multi-dimensional slice to all dimensions.

Example:

>>> from numpy import arange
>>> a = arange(16).reshape(2,2,2,2)

Now, you have a 4-dimensional matrix of order 2x2x2x2. To select all first elements in the 4th dimension, you can use the ellipsis notation

>>> a[..., 0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

which is equivalent to

>>> a[:,:,:,0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

In your own implementations, you’re free to ignore the contract mentioned above and use it for whatever you see fit.


回答 2

这是Ellipsis的另一种用法,它与切片没有关系:我经常在与队列的线程内通信中使用它,作为信号表示“完成”;它在那里,它是一个对象,它是一个单例,其名称表示“缺乏”,而且不是过度使用的None(可以将其作为常规数据流的一部分放入队列中)。YMMV。

This is another use for Ellipsis, which has nothing to do with slices: I often use it in intra-thread communication with queues, as a mark that signals “Done”; it’s there, it’s an object, it’s a singleton, and its name means “lack of”, and it’s not the overused None (which could be put in a queue as part of normal data flow). YMMV.


回答 3

如其他答案中所述,它可用于创建切片。当您不想编写许多完整的切片符号(:),或者只是不确定要操纵的数组的维数是什么时,此功能很有用。

我认为重要的是要突出显示,而其他答案都没有,那就是即使没有更多要填充的尺寸,也可以使用它。

例:

>>> from numpy import arange
>>> a = arange(4).reshape(2,2)

这将导致错误:

>>> a[:,0,:]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: too many indices for array

这将起作用:

a[...,0,:]
array([0, 1])

As stated in other answers, it can be used for creating slices. Useful when you do not want to write many full slices notations (:), or when you are just not sure on what is dimensionality of the array being manipulated.

What I thought important to highlight, and that was missing on the other answers, is that it can be used even when there is no more dimensions to be filled.

Example:

>>> from numpy import arange
>>> a = arange(4).reshape(2,2)

This will result in error:

>>> a[:,0,:]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: too many indices for array

This will work:

a[...,0,:]
array([0, 1])