簡體   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