【问题标题】:How to iterate over a slice?如何迭代切片?
【发布时间】:2019-07-23 07:09:07
【问题描述】:

python 中的slice 是不可迭代的。这段代码:

s = slice(1, 10, 2)
iter(s)

导致此错误:

TypeError: 'slice' object is not iterable

这是我通过创建可迭代列表来显示切片的代码:

list(range(s.start, s.stop, s.step))

这使用切片对象的startstopstep 属性。我将它们插入一个范围(不可变的序列类型)并创建一个列表:

[1, 3, 5, 7, 9]

有什么遗漏吗?我可以更好地迭代切片吗?

【问题讨论】:

  • 你不应该只需要一个range(1, 10, 2)吗?
  • 范围或多或少与切片非常相似,因此我可以使用范围来生成该序列,但我专注于深入了解切片是什么以及如何操作它。切片不是先来的吗?那么范围呢? Range 似乎是一个生成器,内存效率更高。
  • 此外,在实现__setitem__ 时,原始问题具有实际相关性,您希望在其中支持切片。
  • range(s.start, s.stop, s.step) 在 s.start 或 s.step 为 None 时不起作用。

标签: python python-3.x loops iterator slice


【解决方案1】:

slice 不是可迭代的。它不包含元素,而是指定如果切片应用于该可迭代对象,则返回其他可迭代对象中的哪些元素。

由于它不是可迭代的,因此您无法对其进行迭代。但是,正如您所发现的,您可以使用 range() 获取它将从应用它的可迭代对象中返回元素的索引 - 您可以对其进行迭代:

s = slice(1, 10, 2)
indices = range(s.start, s.stop, s.step)
it = iter(indices)

>>> list(it)
[1, 3, 5, 7, 9]

【讨论】:

  • 我想到了将 slice() 子类化。 class Myslice(slice): 然后 def __getitem__(self,key) 但我不知道还要放什么。目前它超出了我的愚蠢程度。
  • 你会发现这有点棘手……class X(slice): pass 的结果是TypeError: type 'slice' is not an acceptable base type
  • 如果可能的话,您将定义一个返回 iter(range(self.start, self.stop, self.step))__iter__ 方法——但鉴于我之前的评论,这一点没有实际意义。
  • 你说......'切片不是可迭代的。它不包含元素,......' 文档说......'......返回一个表示索引集的切片对象......',现在,'索引集' - 它们不是'元素'? “元素”有更具体的定义吗?
  • 在这种情况下,“索引集”不是元素,不是。它们是“您将获得的元素所在的位置,无论您将此切片应用于什么”。另外,请注意使用的词是“代表”,而不是“包含”。将切片视为类似于函数签名可能会有所帮助。这不是一个东西,这是一个描述。
【解决方案2】:

将切片转换为范围,然后可以迭代范围。

range(10**10)[slice]

【讨论】:

  • 顺便提一下,为什么 range 需要 stop 参数?为什么不默认为无穷大?似乎range() 对于非负整数范围来说是一个很好的习惯用法。
  • 当我这样做的时候,我刚刚拿回了切片 - 但做 list(range(1000))[slicer] 工作给了我价值。 (Python 3)。
  • list(range(1000)) 是次优的,因为它必须填满内存,如果你希望它有效地无限,这是一个问题。
  • “当我这样做时,我刚刚得到了切片”不,你得到了一个表现得像切片的范围。不同之处在于您可以迭代范围。您不能迭代切片。见原帖。 ```
  • 嗯...你是对的。我一定是打错字什么的,因为我以为我做了同样的事情,type(foo) 是一个切片。这次是类型范围,并且没有列表就可以很好地迭代。呜呜呜。
【解决方案3】:

问题比答案更笼统。 Slice 可以将浮点数作为一个步骤,其中 range 只能采用整数。所以更一般地说:

test=slice(0,1,0.01)
testlist=[x*test.step for x in range(0,int((test.stop-test.start)/test.step+1))]

您可能会遇到舍入错误,其中讨论了替代方案here

【讨论】:

    猜你喜欢
    • 2015-06-08
    • 1970-01-01
    • 2015-02-04
    • 2023-01-08
    • 2010-11-23
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    相关资源
    最近更新 更多