【问题标题】:"Slicing" in Python Expressions documentationPython 表达式文档中的“切片”
【发布时间】:2010-10-19 15:37:58
【问题描述】:

我不理解 Python 文档的以下部分:

http://docs.python.org/reference/expressions.html#slicings

这是指列表切片 (x=[1,2,3,4]; x[0:2])..?特别是提到省略号的部分..

slice_item       ::=  expression | proper_slice | ellipsis

作为表达式的切片项的转换就是那个表达式。省略号切片项的转换是内置的省略号对象。

【问题讨论】:

    标签: python syntax


    【解决方案1】:

    Ellipsis主要由numeric python扩展使用,它增加了一个多维数组类型。由于有多个维度,slicing 变得比仅仅一个开始和停止索引更复杂;能够在多个维度上切片也很有用。例如,给定一个 4x4 数组,左上角区域将由切片 "[: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 数组,a[...,0]a[:,:,0] 相同,对于 4d,a[:,:,:,0]

    请注意,虽然有一个内置的 Ellipsis 对象,但实际的 Ellipsis 文字 (...) 在 python2 中的切片语法之外是不可用的。这就是“省略号切片项的转换是内置的省略号对象”的意思。 IE。 “a[...]”实际上是“a[Ellipsis]”的糖。在python3中,...表示任何地方的省略号,所以你可以这样写:

    >>> ...
    Ellipsis
    

    如果你不使用 numpy,你几乎可以忽略所有提到的省略号。没有任何内置类型使用它,所以您真正需要关心的是列表传递一个切片对象,其中包含“start”、“stop”和“step”成员。即:

    l[start:stop:step]   # proper_slice syntax from the docs you quote.
    

    相当于调用:

    l.__getitem__(slice(start, stop, step))
    

    【讨论】:

    • “请注意,实际的省略号文字 (...) 在 python2 中的切片语法之外不可用”语句并不完全准确。您可以通过以下方式使用“...”。 a[3,...,5] ,假设 a 是定义 __getitem__(self, key) 的类实例。正确的说法是省略号在索引查找运算符之外不可用。
    • @abc: a[3, ..., 5] 在技术上是切片语法。
    • @user2357112supportsMonica,我在 python2 和 python3 中都尝试了a = [0,1,2,3,4,5,6,7]; print(a[3, ..., 5]),两次都得到:TypeError: list indices must be integers, not tuple
    【解决方案2】:

    定义简单的测试类,只打印正在传递的内容:

    >>> class TestGetitem(object):
    ...   def __getitem__(self, item):
    ...     print type(item), item
    ... 
    >>> t = TestGetitem()
    

    表达式示例:

    >>> t[1]
    <type 'int'> 1
    >>> t[3-2]
    <type 'int'> 1
    >>> t['test']
    <type 'str'> test
    >>> t[t]
    <class '__main__.TestGetitem'> <__main__.TestGetitem object at 0xb7e9bc4c>
    

    切片示例:

    >>> t[1:2]
    <type 'slice'> slice(1, 2, None)
    >>> t[1:'this':t]
    <type 'slice'> slice(1, 'this', <__main__.TestGetitem object at 0xb7e9bc4c>)
    

    省略号示例:

    >>> t[...]
    <type 'ellipsis'> Ellipsis
    

    带有省略号和切片的元组:

    >>> t[...,1:]
    <type 'tuple'> (Ellipsis, slice(1, None, None))
    

    【讨论】:

      【解决方案3】:

      发生的事情是这样的。见http://docs.python.org/reference/datamodel.html#typeshttp://docs.python.org/library/functions.html#slice

      切片对象用于表示 当扩展切片语法为切片时 用过的。这是使用两个切片 冒号,或多个切片或椭圆 用逗号分隔,例如, a[i:j:step]、a[i:j, k:l] 或 a[..., 我:j]。它们也是由 内置 slice() 函数。

      特殊的只读属性:start is 下限;停止是上部 边界; step 是步长值;每个都是 如果省略则无。这些属性可以 有任何类型。

      x=[1,2,3,4]
      x[0:2]
      

      “0:2”被转换为Slice对象,开始为0,停止为2,步为无。

      Slice 对象提供给您定义的类的x__getitem__ 方法。

      >>> class MyClass( object ):
          def __getitem__( self, key ):
              print type(key), key
      
      
      >>> x=MyClass()
      >>> x[0:2]
      <type 'slice'> slice(0, 2, None)
      

      但是,对于内置列表类,必须重写一个特殊的 __getslice__ 方法。

      class MyList( list ):
          def __getslice__( self, i, j=None, k=None ):
              # decode various parts of the slice values
      

      省略号是一种特殊的“忽略此维度”语法,提供给多维切片。

      有关更多信息,另请参阅http://docs.python.org/library/itertools.html#itertools.islice

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-18
        • 2015-03-09
        • 2018-08-31
        • 2017-05-24
        • 2011-04-18
        • 2016-09-23
        相关资源
        最近更新 更多