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


Answers:


102

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

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

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

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

>>> 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文档语言参考。但是这些不是很有帮助。


6
看起来很残破,因为“正确”的说法是所有项目都是>>> x [:] >>> x [:, 1:2]
罗尼(Ronny)

30
@Ronny:重点是演示一些省略号的自定义用法。
nosklo

7
链接似乎已断开。
SwiftsNamesake

230

省略号用在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])

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


也许我是错的,但不是a[:,:,:,0]会返回副本并a[...,0]返回“视图”而不是副本吗?我尝试id()同时针对版本和3-dim数组运行: a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] 所有ID均不同,而:a[..., 0], a[..., 1], a[..., 2] ID均相同。
mohitsharma44

@ mohitsharma44不在我的计算机上;)id()两者都返回相同的值。还要检查与__array_interface__['data']显示相同的内存地址。
BoltzmannBrain

我发现a[indexes, ...]即使a是一维数组,我们也可以使用!
挑衅者'17

1
椭圆对于零维数据结构也很有用。它们是我知道写入标量numpy.ndarrays的唯一方法,例如:my_scalar = np.asarray(3);。my_scalar [...] =5。如果您执行my_scalar [:] = 5,您将正确地得到一个错误,因为:没有要迭代的维0。
SuperElectric

1
@SuperElectric您也可以使用my_scalar.itemset(scalarvalue)。当然,my_scalar [...] = scalar_value短一些,但是您在上面的评论中说过,这是唯一知道的方法。只是给替代。
kamathln

70

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


14
在某处说“ Done = object()”并使用它可能更清晰吗?
布兰登·罗兹

12
不一定-它要求您实际在某处 Done = object()。前哨值不一定是一件坏事-使用原本几乎无用的Python单例作为哨兵并不会使IMO太恐怖(Ellipsis和()是我在没有None会造成混淆的地方使用的那些)。
里克·科普兰

6
关于Done = object(),我认为使用Ellipsis更好,特别是如果您将其用于与队列通信时。如果您从线程内通信转到进程内通信,则id(Done)在另一个进程中将是不同的,并且没有什么可将一个对象与另一个对象区分开。Ellipsis的id也不相同,但至少类型是相同的-这是单例的要点。
Tristan Reid 2013年

问题是“您如何使用省略号”,但我相信您的做法是错误的。它有许多解释。但是我认为正确的是:“如何使用省略号?” 即“我应该采取哪些步骤在自己的代码中使用省略号”。
Lyndon White

6

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

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

例:

>>> 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])
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.