订阅itertools.repeat

时间:2012-11-23 16:19:58

标签: python python-3.x itertools

鉴于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

2 个答案:

答案 0 :(得分:3)

repeat一次又一次地产生同一个对象。我真的不确定它实际上会为你做什么订阅...你也可以打电话给next(repeat_object)。也许你正在考虑cycle(就像我最初读你的问题时那样)?

itertools的一个奇迹是,它试图尽可能懒惰地运作。鉴于此,如果将生成器表达式传递给itertools.cycle,您会发生什么? cycle NO WAY 知道您传递的对象的长度,而不是将整个内容转换为元组并进行查询。这样做可能会破坏许多其他地方的API(现在你在下载重复对象时使用你的iterable),或者通过不必要的itertools.tee需要更多的中间存储 - 这就是{ {1}}试图避免。正如当前实现的那样,itertools对一个巨大的生成器表达式你不能希望在内存中保存(只要你实际上没有迭代所有元素),但那不是如果你试图在一个大的索引处下标它。

最后,顾名思义,cycle是用于创建itertools个对象的库。因此,没有理由期望对象是可订阅的。 (毕竟,它并没有被称为iterable。)。

作为旁注,您可以使用subscripttools执行所需操作。

答案 1 :(得分:0)

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

以下是文档说的内容: -

  

创建一个一遍又一遍地返回对象的迭代器。运行   无限期,除非指定了times参数。

来自documentation of range: -

  

如果你确实需要迭代一系列数字,那么内置   功能范围()派上用场。它生成包含的列表   算术进展


Python 3 中,区别在于,range()创建了一个Generator对象。 Python 2 中的哪个xrange函数。