python raise stopiteration_python 迭代器 一个奇怪的解决方法

一般我们在类里面写迭代器都是如下写法:

1 classIterableSomthing:2 def __iter__(self):3 returnself4

5 def __next__(self):6 return 1

但是,《流畅的python》给出了不同的见解。该书指出,在数据结构内实现迭代器是个很蠢的想法,因为需要引入游标指针记录位置的缘故,这么实现迭代器会造成数据结构空间性能下降,同时,因为游标指针的独立性使得改数据结构无法并发遍历,所以又造成了时间性能的下降。代码如下

1 classNode:2 def __init__(self, item):3 self.item =item4 self.pre =None5 self.next =None6

7

8 classDeque:9 def __init__(self):10 """创建一个空的双端队列"""

11 self.head =None12 self.tail =None13 self.point =self.head #游标指针14

15 defadd_front(self, item):16 """从队头加入一个item元素"""

17 n0 =Node(item)18 ifself.head:19 n0.next =self.head20 self.head.pre =n021 self.head =n022 else:23 self.head =n024 self.tail =n025 self.zero()26

27 defadd_rear(self, item):28 """从队尾加入一个item元素"""

29 n0 =Node(item)30 ifself.tail:31 n0.pre =self.tail32 self.tail.next =n033 self.tail =n034 else:35 self.head =n036 self.tail =n037 self.zero()38

39 defremove_front(self):40 """从队头删除一个item元素"""

41 ifself.head:42 if self.head ==self.tail:43 self.head =None44 self.tail =None45 else:46 self.head.next.pre =None47 self.head =self.head.next48 self.zero()49

50 defremove_rear(self):51 """从队尾删除一个item元素"""

52 ifself.tail:53 if self.head ==self.tail:54 self.head =None55 self.tail =None56 else:57 self.tail.pre.next =None58 self.tail =self.tail.pre59 self.zero()60

61 defis_empty(self):62 """判断双端队列是否为空"""

63 return self.head isNone64

65 defsize(self):66 """返回队列的大小"""

67 i =068 n0 =self.head69 whilen0:70 i += 1

71 n0 =n0.next72 returni73

74 deftolist(self):75 li =[]76 n0 =self.head77 whilen0:78 li.append(n0.item)79 n0 =n0.next80 returnli81

82 defgen(self):83 n0 =self.head84 whilen0:85 #print(id(self))

86 yieldn0.item87 n0 =n0.next88 raiseStopIteration89

90 def __iter__(self):91 #n0 = self.head

92 #while n0:

93 ## print(id(self))

94 #yield n0.item

95 #n0 = n0.next

96 #raise StopIteration

97 returnself98

99 def __next__(self):100 ifself.point:101 n0 =self.point102 self.point =self.point.next103 returnn0.item104 else:105 self.zero()106 raiseStopIteration107

108 defzero(self): #游标指针归零函数109 self.point = self.head

这是个双端队列的python实现,如果实现了迭代器,就必须实现游标指针类属性,游标指针归零类方法,着实降低了开发效率

有没有别的解决方法呢?

只要改一处:

1 def __iter__(self):2 __index_temp = self.__head

3 while __index_temp:4 n0 = __index_temp

5 __index_temp = __index_temp.next6 yieldn07 else:8 raise StopIteration

对你没看错,没有__next__函数!没有游标指针!没有归零函数!

这个__iter__函数需要返回一个迭代器,我们就给他一个,因为生成器也是迭代器!

此时,这个双端队列的python实现就不是一个迭代器了,而是一个可迭代对象,就可以用for循环迭代了

deftest2():

s1=DoubleLinkList()for i in range(1000):

s1.append(i)for ii ins1:print(ii.item)if ii.item == 500:print('------------------------------------------------------------------------------')break

for ii ins1:print(ii.item)

而且每一个for循环都是独立的,因为每个for循环块获得的对象都是一个独立的生成器,相互之间不会干扰,虽然看起来都是调用同一个对象,但实际上完全不是这么一回事,这就和list的实现是一样一样的,这样的话做并发循环就容易多了。

思考:python里的魔术方法都很有用,但是我们是要为了实现某个功能专门实现对应的魔术方法呢,还是直接实现对应的功能函数呢?

魔术方法是为了其他方法服务的基本方法,还是锦上添花的增补手段呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值