如何迭代切片?

Posted

技术标签:

【中文标题】如何迭代切片?【英文标题】: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 时不起作用。 【参考方案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

【讨论】:

以上是关于如何迭代切片?的主要内容,如果未能解决你的问题,请参考以下文章

如何对迭代器做切片操作?

带有迭代的 Pandas DataFrame 切片

Numpy数组对象的操作-索引机制切片和迭代方法

对迭代器进行切片

迭代器切片操作

迭代列表切片