繁体   English   中英

如何检查迭代器是否实际上是迭代器容器?

[英]How do I check if an iterator is actually an iterator container?

我有一个下面的迭代器容器的虚拟示例(真正的读取文件太大而不适合内存):

class DummyIterator:
    def __init__(self, max_value):
        self.max_value = max_value

    def __iter__(self):
        for i in range(self.max_value):
            yield i

def regular_dummy_iterator(max_value):
    for i in range(max_value):
        yield i

这允许我多次迭代该值以便我可以实现这样的事情:

def normalise(data):
    total = sum(i for i in data)
    for val in data:
        yield val / total

# this works when I call next()
normalise(DummyIterator(100))

# this doesn't work when I call next()
normalise(regular_dummy_iterator(100))

如何检查normalize函数,我正在传递一个迭代器容器而不是一个普通的生成器?

首先:没有迭代器容器这样的东西。 你有一个可迭代的

迭代生成迭代器。 任何迭代器也是可迭代的,但它自己生成迭代器:

>>> list_iter = iter([])
>>> iter(list_iter) is list_iter
True

如果iter(ob) is ob test,则没有迭代器。

您可以使用collections.abc模块测试是否有迭代器( next一次使用StopIteration异常消耗)与只有迭代(可能多次迭代)。 这是一个例子:

from collections.abc import Iterable, Iterator

def my_iterator(): 
    yield 1

i = my_iterator()
a = []

isinstance(i, Iterator) # True
isinstance(a, Iterator) # False

是什么让my_iterator()Iterator是既存在__next____iter__魔术方法(顺便说一句,基本上发生了什么事,当你调用幕后isinstancecollections.abc抽象基类是存在的测试某些神奇的方法)。

注意迭代器也是一个Iterable ,就像空列表一样(即两者都有__iter__魔术方法):

isinstance(i, Iterable) # True
isinstance(a, Iterable) # True

还要注意, 正如Martijn Pieters的回答所指出的 ,当你将泛型iter()函数应用于两者时,你会得到一个迭代器:

isinstance(iter(my_iterator()), Iterator) # True
isinstance(iter([])), Iterator) # True

[]my_iterator()之间的区别在于iter(my_iterator()) 将自身作为迭代器返回 ,而iter([])每次都会生成一个新的迭代器

正如在MP的相同答案中已经提到的,上面的对象不是“迭代器容器”。 它是一个可迭代的对象,即“可迭代的”。 它是否“包含”某些东西并不是真正相关的; contains的概念由抽象基类Container Container可以是可迭代的,但它不一定必须是可迭代的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM