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

How do you use the ellipsis slicing syntax in Python?

提问人:miracle2k 提问时间:9/23/2008 最后编辑:Communitymiracle2k 更新时间:12/7/2022 访问量:65260

问:

这出现在 Python 的隐藏功能中,但我看不到解释该功能如何工作的良好文档或示例。

Python numpy 子类 省略号

评论


答:

132赞 nosklo 9/23/2008 #1

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

评论

8赞 5/8/2009
看起来很破,因为“propper”表示所有项目的方式是>>> x[:] >>> x[:, 1:2]
37赞 nosklo 5/8/2009
@Ronny:重点是演示省略号的一些自定义用法。
9赞 SwiftsNamesake 2/26/2015
链接似乎已损坏。
307赞 Torsten Marek 9/23/2008 #2

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

在你自己的实现中,你可以自由地忽略上面提到的协定,并将其用于你认为合适的任何事情。

评论

1赞 mohitsharma44 10/6/2016
也许我错了,但这不是会返回一个副本并返回“视图”而不是副本吗?我尝试针对两个版本和 3-dim 数组运行:它们都有不同的 id,而:它们都有相同的 id。a[:,:,:,0]a[...,0]id()a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] a[..., 0], a[..., 1], a[..., 2]
1赞 BoltzmannBrain 3/31/2017
@mohitsharma44不在我的机器上;) 两者返回相同的值。此外,使用 __array_interface__['data'] 检查会显示相同的内存地址。id()
4赞 kmario23 1/20/2018
什么是四维矩阵?将其称为 4 维数组而不是矩阵是有意义的,IMO。
5赞 SuperElectric 2/13/2018
椭圆对于零维数据结构也很有用。它们是我所知道的写入标量 numpy.ndarrays 的唯一方法,例如: my_scalar = np.asarray(3);my_scalar[...] = 5。如果执行 my_scalar[:] = 5,则理所当然地会得到错误,因为 : 没有维度 0 可供迭代。
3赞 kamathln 3/2/2018
@SuperElectric 您还可以使用 my_scalar.itemset(scalarvalue)。当然,my_scalar[...]=scalar_value 更短,但你在上面的评论中说,这是你唯一知道的方式。只是给出一个替代方案。
74赞 tzot 9/23/2008 #3

这是省略号的另一个用途,它与切片无关:我经常在与队列的线程内通信中使用它,作为表示“完成”的标记;它就在那里,它是一个对象,它是一个单例,它的名字的意思是“缺乏”,它不是过度使用的 None(可以作为正常数据流的一部分放入队列中)。YMMV。

评论

15赞 Brandon Rhodes 4/21/2009
只是在某处说:“Done = object()”并使用它不是更清楚吗?
13赞 Rick Copeland 6/22/2009
不一定 - 它需要你实际在某处 Done=object()。哨兵值不一定是坏事——使用其他几乎无用的 Python 单例作为哨兵并不是那么可怕 IMO(省略号和 () 是我使用过的那些,None 会混淆)。
7赞 Tristan Reid 1/19/2013
关于 Done = object(),我认为使用省略号更好,尤其是当您使用它与队列进行通信时。如果从线程内通信转到进程内通信,则 id(Done) 在另一个进程中将不相同,并且没有什么可以区分一个对象和另一个对象。Ellipsis 的 id 也不会相同,但至少类型会相同 - 这是单例的重点。
0赞 Frames Catherine White 12/23/2014
问题说“你如何使用省略号”,但我相信你走错了路。它有很多解释。但我认为正确的是:“如何使用省略号?”即“我应该采取哪些步骤在我自己的代码中使用省略号。
15赞 Mauricio Perez 6/7/2018 #4

如其他答案所述,它可用于创建切片。 当您不想编写许多完整切片表示法 () 时,或者当您不确定作的数组的维度是多少时,这很有用。:

我认为需要强调的重要一点是,即使没有更多维度需要填充,也可以使用它。

例:

>>> 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])

评论

0赞 mins 10/28/2023
"这当然会起作用“,但我们对它起作用的原因很感兴趣。也许是因为 Numpy 解释为“在给定数组形状的情况下添加创建有效索引所需的正确数量”。在您的示例中,它不添加任何内容,对于 3D 数组,它会添加,对于 4D 数组,它会添加 ,依此类推。 这种解释是 Numpy 的解释,但另一个包或其他开发人员可能会以完全不同的方式解释,前提是他们解释了如何使用它。...:,:,:, :,...