如何在Python 3中实现切片?

8 投票
4 回答
5063 浏览
提问于 2025-04-16 23:45

我看了一些关于Python 3中切片(slice)的内容。然后我写了一个程序,尝试实现 __getitem__(self, slice(s))。下面是我的代码:

class NewList:
    def __init__(self, lst):
        print('new list')
        self._list = lst
    def __getitem__(self, x):
        if type(x) is slice:
            return [ self._list[n] for n in range(x.start, x.stop, x.step) ]  #error?
        else:
            return self._list[x]
    ...

nl1 = NewList([1,2,3,4,5])
nl1[1:3]  #error occurs

然后我发现 x.stepNone,这导致范围(range)抛出了一个异常。那么,我应该怎么实现 __getitem__ 方法呢?

4 个回答

1

如果x是一个切片,你可以像其他条件一样进行操作:

return self._list[x]
4

如果你不知道你的对象有多长,其实有一个简单的方法可以绕过这个必须要提供的参数。比如说,一个无限序列的getitem可以这样写:

  def __getitem__( self, key ) :
    if isinstance( key, slice ) :
       m = max(key.start, key.stop)
       return [self[ii] for ii in xrange(*key.indices(m+1))]
    elif isinstance( key, int ) :
       #Handle int indices

这样的话,只有在你不提供开始和结束的时候才会出错,不过通过检查是否为None,这个问题也可以解决。

5

你需要使用 slice.indices 这个方法。给定你序列的长度,它会返回一个包含开始位置、结束位置和步长的元组:

>>> s = slice(2, 5, None)
>>> s.indices(10)
(2, 5, 1)

>>> [x for x in range(*s.indices(10))]
[2, 3, 4]

>>> s.indices(3)
(2, 3, 1)

>>> s.indices(0)
(0, 0, 1)

撰写回答