为了账号安全,请及时绑定邮箱和手机立即绑定

可以将迭代器/生成器视为流吗?

可以将迭代器/生成器视为流吗?

qq_遁去的一_1 2022-07-05 15:35:45
我正在阅读 SICP 并最终进入了流的一部分。python 迭代器/生成器可以被视为流吗?这个迭代器例如:class MyNumbers:  def __iter__(self):    self.a = 1    return self  def __next__(self):    x = self.a    self.a += 1    return xmyclass = MyNumbers()myiter = iter(myclass)print(next(myiter))print(next(myiter))print(next(myiter))print(next(myiter))print(next(myiter))满足定义:流是随时间可用的一系列数据元素。流可以被认为是传送带上一次处理一个而不是大批量处理的项目。https://en.wikipedia.org/wiki/Stream_(computing)
查看完整描述

3 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

您引用的维基百科文章继续:

在面向对象编程中,输入流通常实现为迭代器。

所以,你去;-)


查看完整回答
反对 回复 2022-07-05
?
12345678_0001

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,它提供了流的实际实现和一些应用。


查看完整回答
反对 回复 2022-07-05
?
守着星空守着你

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


查看完整回答
反对 回复 2022-07-05
  • 3 回答
  • 0 关注
  • 127 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号