2

鉴于range对象是可下标的,为什么itertools.repeat对象不能下标?

In [10]: range(3, 10)[3]
Out[10]: 6

In [11]: import itertools as it

In [12]: it.repeat(5)[3]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-1ef74480e0a7> in <module>()
----> 1 it.repeat(5)[3]

TypeError: 'itertools.repeat' object is not subscriptable

请注意,范围对象和 itertools.repeat 对象是 Python 3 的一部分。

我会比较喜欢:

class repeat_(itertools.repeat):
    def __init__(self, object_, times=None):
        super().__init__(object_, times)

        self.object_ = object_
        self.times = times

    def __reversed__(self):
        return self

    def __getitem__(self, key):
        return self.object_

    def __contains__(self, key):
        return key == self.object_

    def __len__(self):
        if self.times is None:
            raise ValueError
        return self.times
4

2 回答 2

4

repeat只是一遍又一遍地产生相同的对象。我不确定它实际上会为你做什么下标......你最好打电话给next(repeat_object). 也许您正在考虑cycle(就像我最初阅读您的问题时所做的那样)?

令人惊奇的itertools是,它试图尽可能地懒惰地运行。鉴于此,如果您将生成器表达式传递给 ,您期望会发生itertools.cycle什么? cycle没有办法知道你传递的对象的长度,而不是把整个东西转换成一个元组并查询。这样做可能会在许多其他地方破坏 API(现在您在为重复对象下标时消耗您的迭代),或者它会通过不必要的方式占用更多的中间存储itertools.tee- 这是itertools试图避免的。按照目前的实施,cycle在一个巨大的生成器表达式上,你不能希望在内存中保存它(只要你实际上没有迭代所有元素),但如果你试图在一个大索引处下标它就不会如此.

最后,顾名思义,itertools是一个用于创建iterable对象的库。因此,没有理由期望这些对象是可下标的。subscripttools(毕竟它没有被调用:)。

作为旁注,您可以使用itertools.islice.

于 2012-11-23T16:32:48.770 回答
0

itertool.repeat()方法返回一个迭代器,而不是一个列表,就像range函数一样。所以,你不能在上面下标。

这是文档中的内容:-

制作一个反复返回对象的迭代器。除非指定了 times 参数,否则无限期运行。

范围的文档中: -

如果您确实需要遍历一系列数字,内置函数 range() 会派上用场。它生成包含算术级数的列表


Python 3中,不同之处在于,range()创建了一个Generator对象。Python 2中的哪个xrange函数做了。

于 2012-11-23T16:22:01.753 回答