循环切片的索引

时间:2015-03-01 04:54:14

标签: python

我试图在python中为类实现__getitem__方法。我想尝试类似......

def __getitem__(self, key):
  if isinstance(key, int):
    return foo(key)
  elif isinstance(key, slice):
    return [foo(k) for k in key]
  else:
    raise TypeError("Invalid index.")

...但每当我真正尝试将其与切片一起使用时,我会收到'slice' object is not iterable错误。在python中执行此操作的正确方法是什么?

3 个答案:

答案 0 :(得分:5)

使用切片的indices()方法,并将结果传递给range()xrange()

>>> slice(2, 5).indices(7)
(2, 5, 1)
>>> range(*slice(2, 5).indices(7))
[2, 3, 4]
>>> range(*slice(2, 10).indices(7))
[2, 3, 4, 5, 6]

答案 1 :(得分:1)

指数可能有效,但你也可以只使用切片的开始,停止和步骤,虽然它们可能是空的,所以你需要做这样的事情......

def __getitem__(self, key):
  if isinstance(key, int):
    return foo(key)
  elif isinstance(key, slice):
    start = key.start if key.start is not None else 0
    stop = key.stop
    step = key.step if key.step is not None else 1
    return [foo(k) for k in range(start, stop, step)]
  else:
    raise TypeError("Invalid index.")

答案 2 :(得分:1)

您遇到的问题是,例外情况是:slice对象不可迭代。我发现思考切片的最佳方式是它是一个给迭代器的指令,以确定它返回的内容。所以如果你想要得到这样的东西:

>>> L = [1, 2, 3, 4]
>>> L[1:3]
[2, 3]

(显然这是使用列表而不是自定义类的简化示例)

传递给__getitem__的切片将具有一些您可以使用的属性:

>>> s = slice(1, 2, 3)
>>> s.start, s.stop, s.step

(1,2,3)

如果您说s = slice(1, 2),则step属性将为None。您可以使用此信息在__getitem__中获取列表,元组或任何您想要的内容:

def __getitem__(self, i):
    if isinstance(i, int):
        return foo(i)
    elif isinstance(i, slice):
        return [foo(k) for k in self.bar[i]]  # where bar is a list/tuple

这可行的原因是因为调用self.bar[i] i所在的切片与调用self.bar[1:2]完全没有区别,因为1:2只是slice }对象是i

希望这有用!