3 回答

TA貢獻1802條經驗 獲得超5個贊
python 迭代器/生成器可以被視為流嗎?
不。
基本上,迭代器懶惰地遍歷一個序列,而流是一個懶惰的序列。
在您給出的示例中,迭代器和流之間的區別變得更加清晰,一個無限的自然數序列。
迭代器
這是一個相當簡單的迭代器,只有next()實現了方法。這個實現是不可迭代的,不符合python的迭代器協議;但是,它將與下面的流實現明顯不同。
class Iterator:
def __init__(self, state=1, compute=lambda x: x + 1):
self.state = state
self.compute = compute
def next(self):
current, self.state = self.state, self.compute(self.state)
return current
natural_number = Iterator()
print(natural_number.next()) # 1
print(natural_number.next()) # 2
print(natural_number.next()) # 3
每次next()被調用時,它都會返回序列的當前元素并改變迭代器的狀態。
溪流
因此,使用 SICP 2,流可以由其第一個元素 定義car(),而流的其余部分定義為cdr()。在 python 中,流可以實現為遞歸構造的惰性鏈表。
class Stream:
def __init__(self, state=1, f=lambda x: x+1):
self.state = state
self.compute = f
def car(self):
return self.state
def cdr(self):
return Stream(self.compute(self.state), self.compute)
sequence_of_natural_numbers = Stream()
sequence_of_natural_numbers.car() # 1
sequence_of_natural_numbers.car() # 1
sequence_of_natural_numbers.cdr().car() # 2
sequence_of_natural_numbers.cdr().cdr().car() # 3
每當car()被調用時,它總是返回相同的元素,即序列的第一個元素。crd()返回Stream具有計算狀態的新值。在這種情況下,流狀態永遠不會發生變化。
如果您想知道流是否有用,我建議您閱讀這篇論文Classical (Co)Recursion: Programming,它提供了流的實際實現和一些應用。

TA貢獻1799條經驗 獲得超8個贊
您的示例既是可迭代的(定義的類__iter__)和迭代器(定義的類__next__)。更準確地說,流是可迭代的,而迭代器是用于迭代流的值(可能是流本身)。
這是您的示例,將迭代器與可迭代對象分開。
class MyNumbers:
def __init__(self, start=1):
self.start = start
def __iter__(self):
return MyNumbersIterator(self.start)
class MyNumbersIterator:
def __init__(self, start):
self.value = start
def __next__(self):
x = self.value
self.value += 1
return x
# prints the numbers 10, 11, 12, ..., 19
for x in itertools.islice(MyNumbers(10), 10):
print(x)
MyNumbers是流:它表示從 開始增加的數字序列start。
MyNumbersIterator在該流上提供一個獨立的迭代器;您可以使用相同的可迭代對象擁有多個迭代器。
x = MyNumbers(10)
i1 = iter(x)
i2 = iter(x)
assert next(i1) == 10 # Does not affect i2
assert next(i2) == 10
添加回答
舉報