标签归档:ellipsis

如何在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])

椭圆对象有什么作用?

问题:椭圆对象有什么作用?

在闲置地浏览命名空间时,我注意到一个看起来很奇怪的对象Ellipsis,它似乎并没有做任何特别的事情,但它是一个全局可用的内置对象。

经过搜索,我发现Numpy和Scipy在切片语法的某些晦涩变体中使用了它……但是几乎没有其他东西。

是否将此对象添加到专门支持Numpy + Scipy的语言中?Ellipsis是否有任何一般意义或用途?

D:\workspace\numpy>python
Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> Ellipsis
Ellipsis

While idly surfing the namespace I noticed an odd looking object called Ellipsis, it does not seem to be or do anything special, but it’s a globally available builtin.

After a search I found that it is used in some obscure variant of the slicing syntax by Numpy and Scipy… but almost nothing else.

Was this object added to the language specifically to support Numpy + Scipy? Does Ellipsis have any generic meaning or use at all?

D:\workspace\numpy>python
Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> Ellipsis
Ellipsis

回答 0

这是最近另一个问题。我将从那里详细说明我的答案

省略号是可以以切片表示法显示的对象。例如:

myList[1:2, ..., 0]

它的解释完全取决于实现该__getitem__函数并在其中看到Ellipsis对象的任何事物,但是其主要(和预期的)用途是在numpy第三方库中,该库添加了多维数组类型。由于存在多个维度,因此切片变得比仅起始索引和终止索引更为复杂;能够在多个维度上切片也很有用。例如,给定一个4×4数组,左上方区域将由slice定义[:2,:2]

>>> a
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12],
       [13, 14, 15, 16]])

>>> a[:2,:2]  # top left
array([[1, 2],
       [5, 6]])

进一步扩展,此处省略号用于表示未指定的其余数组尺寸的占位符。可以认为它表示所[:]放置间隙中所有维度的完整切片,因此对于3d数组,与4d a[...,0]相同,同样是(但中间有许多冒号组成了完整数数组中的尺寸)。a[:,:,0]a[:,:,:,0]a[0,...,0]a[0,:,:,0]

有趣的是,在python3中,省略号文字(...)在slice语法之外可用,因此您实际上可以编写:

>>> ...
Ellipsis

除了各种数字类型,不,我认为它没有被使用。据我所知,它纯粹是为numpy使用而添加的,除了提供对象和相应的语法外,没有其他核心支持。那里的对象不需要这个,但是对切片的字面量“ …”支持确实需要。

This came up in another question recently. I’ll elaborate on my answer from there:

Ellipsis is an object that can appear in slice notation. For example:

myList[1:2, ..., 0]

Its interpretation is purely up to whatever implements the __getitem__ function and sees Ellipsis objects there, but its main (and intended) use is in the numpy third-party library, which adds a multidimensional array type. Since there are more than one dimensions, slicing becomes more complex than just a start and stop index; it is useful to be able to slice in multiple dimensions as well. E.g., given a 4×4 array, the top left area would be defined by the slice [:2,:2]:

>>> a
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12],
       [13, 14, 15, 16]])

>>> a[:2,:2]  # top left
array([[1, 2],
       [5, 6]])

Extending this further, Ellipsis is used here to indicate a placeholder for the rest of the array dimensions not specified. Think of it as indicating the full slice [:] for all the dimensions in the gap it is placed, so for a 3d array, a[...,0] is the same as a[:,:,0] and for 4d, a[:,:,:,0], similarly, a[0,...,0] is a[0,:,:,0] (with however many colons in the middle make up the full number of dimensions in the array).

Interestingly, in python3, the Ellipsis literal (...) is usable outside the slice syntax, so you can actually write:

>>> ...
Ellipsis

Other than the various numeric types, no, I don’t think it’s used. As far as I’m aware, it was added purely for numpy use and has no core support other than providing the object and corresponding syntax. The object being there didn’t require this, but the literal “…” support for slices did.


回答 1

在Python 3中,您可以将Ellipsis文字...用作代码的“ nop”占位符:

def will_do_something():
    ...

不是魔术。可以使用任何表达式代替...,例如:

def will_do_something():
    1

(不能使用“批准”一词,但我可以说Guido 并未完全拒绝这种使用。)

In Python 3, you can use the Ellipsis literal ... as a “nop” placeholder for code:

def will_do_something():
    ...

This is not magic; any expression can be used instead of ..., e.g.:

def will_do_something():
    1

(Can’t use the word “sanctioned”, but I can say that this use was not outrightly rejected by Guido.)


回答 2

从Python 3.5和PEP484开始,使用键入模块时,文字省略号用于表示静态类型检查器的某些类型。

范例1:

任意长度的均值元组可以使用一种类型和省略号表示,例如 Tuple[int, ...]

范例2:

通过用文字省略号(三个点)代替参数列表,可以在不指定调用签名的情况下声明可调用对象的返回类型:

def partial(func: Callable[..., str], *args) -> Callable[..., str]:
    # Body

As of Python 3.5 and PEP484, the literal ellipsis is used to denote certain types to a static type checker when using the typing module.

Example 1:

Arbitrary-length homogeneous tuples can be expressed using one type and ellipsis, for example Tuple[int, ...]

Example 2:

It is possible to declare the return type of a callable without specifying the call signature by substituting a literal ellipsis (three dots) for the list of arguments:

def partial(func: Callable[..., str], *args) -> Callable[..., str]:
    # Body

回答 3

在指定预期的doctest输出时,也可以使用省略号:

class MyClass(object):
    """Example of a doctest Ellipsis

    >>> thing = MyClass()
    >>> # Match <class '__main__.MyClass'> and <class '%(module).MyClass'>
    >>> type(thing)           # doctest:+ELLIPSIS
    <class '....MyClass'>
    """
    pass

You can also use the Ellipsis when specifying expected doctest output:

class MyClass(object):
    """Example of a doctest Ellipsis

    >>> thing = MyClass()
    >>> # Match <class '__main__.MyClass'> and <class '%(module).MyClass'>
    >>> type(thing)           # doctest:+ELLIPSIS
    <class '....MyClass'>
    """
    pass

回答 4

Python文档中

切片通常使用此对象(请参阅切片)。它不支持任何特殊操作。恰好有一个省略号对象,名为Ellipsis(内置名称)。type(Ellipsis)()产生Ellipsis单例。

它写为Ellipsis...

From the Python documentation:

This object is commonly used by slicing (see Slicings). It supports no special operations. There is exactly one ellipsis object, named Ellipsis (a built-in name). type(Ellipsis)() produces the Ellipsis singleton.

It is written as Ellipsis or ....


回答 5

总结其他人所说的内容,从Python 3开始,Ellipsis本质上是与相似的另一个单例常量None,但没有特定的预期用途。现有用途包括:

  • 以切片语法表示剩余维度中的完整切片
  • 在类型提示中仅指示类型(Callable[..., int]Tuple[str, ...])的一部分
  • 在类型存根文件中以指示存在默认值而不指定它

可能的用途包括:

  • 作为None有效选项的地方的默认值
  • 作为尚未实现的功能的内容

Summing up what others have said, as of Python 3, Ellipsis is essentially another singleton constant similar to None, but without a particular intended use. Existing uses include:

  • In slice syntax to represent the full slice in remaining dimensions
  • In type hinting to indicate only part of a type(Callable[..., int] or Tuple[str, ...])
  • In type stub files to indicate there is a default value without specifying it

Possible uses could include:

  • As a default value for places where None is a valid option
  • As the content for a function you haven’t implemented yet

回答 6

__getitem__...自定义类中的最小示例

在自定义类中...传递魔术语法时[],将__getitem__()接收一个Ellipsis类对象。

然后,该类可以使用此Singleton对象执行任何所需的操作。

例:

class C(object):
    def __getitem__(self, k):
        return k

# Single argument is passed directly.
assert C()[0] == 0

# Multiple indices generate a tuple.
assert C()[0, 1] == (0, 1)

# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)

# Ellipsis notation generates the Ellipsis class object.
# Ellipsis is a singleton, so we can compare with `is`.
assert C()[...] is Ellipsis

# Everything mixed up.
assert C()[1, 2:3:4, ..., 6] == (1, slice(2,3,4), Ellipsis, 6)

Python内置list类选择给它提供范围的语义,当然,对它的任何合理使用也应如此。

就个人而言,我只是在我的API中远离它,而是创建一个单独的,更明确的方法。

已在Python 3.5.2和2.7.12中测试。

__getitem__ minimal ... example in a custom class

When the magic syntax ... gets passed to [] in a custom class, __getitem__() receives a Ellipsis class object.

The class can then do whatever it wants with this Singleton object.

Example:

class C(object):
    def __getitem__(self, k):
        return k

# Single argument is passed directly.
assert C()[0] == 0

# Multiple indices generate a tuple.
assert C()[0, 1] == (0, 1)

# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)

# Ellipsis notation generates the Ellipsis class object.
# Ellipsis is a singleton, so we can compare with `is`.
assert C()[...] is Ellipsis

# Everything mixed up.
assert C()[1, 2:3:4, ..., 6] == (1, slice(2,3,4), Ellipsis, 6)

The Python built-in list class chooses to give it the semantic of a range, and any sane usage of it should too of course.

Personally, I’d just stay away from it in my APIs, and create a separate, more explicit method instead.

Tested in Python 3.5.2 and 2.7.12.


回答 7

您可以在numpy这样的自定义切片情况下自己使用Ellipsis,但在任何内置类中都没有用。

我不知道是否专门为numpy添加了它,但我当然没有看到它在其他地方使用。

另请参阅:如何在Python中使用省略号切片语法?

You can use Ellipsis yourself, in custom slicing situations like numpy has done, but it has no usage in any builtin class.

I don’t know if it was added specifically for use in numpy, but I certainly haven’t seen it used elsewhere.

See also: How do you use the ellipsis slicing syntax in Python?


回答 8

正如@noɥʇʎԀʎzɐɹƆ和@phoenix提到的-您确实可以在存根文件中使用它。例如

class Foo:
    bar: Any = ...
    def __init__(self, name: str=...) -> None: ...

有关如何使用此省略号的更多信息和示例,请参见https://www.python.org/dev/peps/pep-0484/#stub-files

As mentioned by @noɥʇʎԀʎzɐɹƆ and @phoenix – You can indeed use it in stub files. e.g.

class Foo:
    bar: Any = ...
    def __init__(self, name: str=...) -> None: ...

More information and examples of how to use this ellipsis can be discovered here https://www.python.org/dev/peps/pep-0484/#stub-files


回答 9

它的预期用途不仅应用于这些第三方模块。在Python文档中没有适当提及(或者也许我找不到),但是CPython实际上至少在一个地方使用省略号...

它用于表示Python中的无限数据结构。我在玩列表时遇到了这个符号。

有关更多信息,请参见此问题

Its intended use shouldn’t be only for these 3rd party modules. It isn’t mentioned properly in the Python documentation (or maybe I just couldn’t find that) but the ellipsis ... is actually used in CPython in at least one place.

It is used for representing infinite data structures in Python. I came upon this notation while playing around with lists.

See this question for more info.


回答 10

这是等效的。

l=[..., 1,2,3]
l=[Ellipsis, 1,2,3]

...是在内部定义的常量built-in constants

省略

与省略号“ …”相同。特殊值,通常与用户定义的容器数据类型的扩展切片语法结合使用。

This is equivalent.

l=[..., 1,2,3]
l=[Ellipsis, 1,2,3]

... is a constant defined inside built-in constants.

Ellipsis

The same as the ellipsis literal “…”. Special value used mostly in conjunction with extended slicing syntax for user-defined container data types.