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
添加回答
举报
