【问题标题】:Python - how slice([1,2,3]) works and what does slice(None, [1, 3], None) represent?Python - slice([1,2,3]) 如何工作以及 slice(None, [1, 3], None) 代表什么?
【发布时间】:2021-04-01 18:17:02
【问题描述】:

Documentation for class slice(start, stop[, step]):

返回一个切片对象,表示由 range(start, stop, step) 指定的索引集。

代码中发生了什么以及为什么 slice 类 init 甚至允许列表作为其参数?

print(slice([1,3]))
---
slice(None, [1, 3], None)

print(slice(list((1,3))))
---
slice(None, [1, 3], None)  # why stop is list?

hoge = [1,2,3,4]
_s = slice(list((1,3)))
print(hoge[_s])
--------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-59-1b2df30e9bdf> in <module>
      1 hoge = [1,2,3,4]
      2 _s = slice(list((1,3)))
----> 3 print(hoge[_s])

TypeError: slice indices must be integers or None or have an __index__ method

更新

感谢塞尔丘克的回答。

sliceobject.c#L303-L322

static PyObject *
slice_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
    PyObject *start, *stop, *step;

    start = stop = step = NULL;

    if (!_PyArg_NoKeywords("slice", kw))
        return NULL;

    if (!PyArg_UnpackTuple(args, "slice", 1, 3, &start, &stop, &step))
        return NULL;

    /* This swapping of stop and start is to maintain similarity with
       range(). */
    if (stop == NULL) {
        stop = start;       // <-----
        start = NULL;
    }
      
    return PySlice_New(start, stop, step);  // PySlice_New in L110 in the same file
}

【问题讨论】:

    标签: python python-3.x slice


    【解决方案1】:

    来自the documentation

    切片对象具有只读数据属性startstopstep,它们仅返回参数值(或其默认值)。它们没有其他明确的功能 [...]

    因此,它们只是保留您传递的任何东西的虚拟对象。你甚至可以传递字符串或其他对象:

    my_slice = slice("foo", "bar", "baz")
    

    [...] 但是它们被 Numerical Python 和其他第三方扩展使用。

    第三方扩展的工作是验证startstopstep 值是否有意义。

    另见CPython implementation

    当您只传递一个参数时,它被假定为stop 值。这就是为什么您最终将 startstep 值设置为 None

    class slice(stop)

    class slice(start, stop[, step])

    【讨论】:

    • 感谢代码指针。我想文档“开始和步骤参数默认为无”表示“只有一个参数停止”。我认为 c 代码本身并没有说明这一点,另一个文档 docs.python.org/3/c-api/slice.html#c.PySlice_New 看起来也不具体......
    • 由于 numpy 显然将列表作为切片表达式np.arange(5)[[1,2]],因此会混淆它是 python 还是 numpy。我想这是 numpy 特定的实现。
    • 在文档中使用替代构造函数明确说明:class slice(stop)。在 C 代码中看到这一点很棘手,但请查看 github.com/python/cpython/blob/master/Objects/…
    猜你喜欢
    • 2019-09-11
    • 2020-11-19
    • 2020-03-19
    • 1970-01-01
    • 2016-03-09
    • 2019-08-12
    • 2019-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多