鱼C论坛

 找回密码
 立即注册
查看: 2443|回复: 3

[学习笔记] 迭代器的坑

[复制链接]
发表于 2020-3-15 17:24:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
看小甲鱼视频时:
眼:“嗯,我看懂了。”,耳朵:“嗯,我听懂了。”,脑子:“嗯,我理解了。”
自己写的时候:
手:“???”

一、问题发现来源于第48讲课后题,先回顾一下:

1. 写一个迭代器,要求输出至今为止的所有闰年。如:
  1. >>> leapYears = LeapYear()
  2. >>> for i in leapYears:
  3.         if i >=2000:
  4.                 print(i)
  5.         else:
  6.                 break

  7. 2012
  8. 2008
  9. 2004
  10. 2000
复制代码


下面是我第一次写的时候,报错的答案:
  1. '''写一个迭代器,要求输出至今为止的所有闰年'''

  2. class LeapYear:
  3.    
  4.     def __init__(self):
  5.         
  6.         self.year = 2020
  7.    
  8.     def __next__(self):
  9.         if ((self.year%4 == 0 and self.year%100 != 0) or (self.year%400 == 0)):
  10.             temp = self.year
  11.             self.year -= 1
  12.             return temp
  13.         else:
  14.             self.year -1
  15.         

  16.     def __iter__(self):
  17.         return self

  18.    
  19.    
  20.         

  21. leapYears = LeapYear()
  22. for i in leapYears:
  23.     if i >=2000:
  24.             print(i)
  25.     else:
  26.             break
复制代码



我的思路是:在__next__()方法里做文章,判断如果是闰年就返回,如果不是就-1
但是却报错:
  1. 2020
  2. Traceback (most recent call last):
  3.   File "F:/Python demo/课后作业/48.1.py", line 27, in <module>
  4.     if i >=2000:
  5. TypeError: '>=' not supported between instances of 'NoneType' and 'int'
复制代码



报错原因:'>='无法在'NoneType'和'int'中进行比较
所以以上代码的错误就在于:如果不是闰年,__next__()方法就返回None,这样肯定是错的。
修改需要只返回闰年,不是闰年就跳过,所以有了下面的正确答案。

  1. import datetime as dt

  2. class LeapYear:
  3.     def __init__(self):
  4.         self.year = dt.date.today().year

  5.     def __iter__(self):
  6.         return self

  7.     def isLeapYear(self, year):
  8.         if ((year%4 == 0 and year%100 != 0) or (year % 400 == 0)):
  9.             return True
  10.         else:
  11.             return False

  12.     def __next__(self):
  13.         while not self.isLeapYear(self.year):
  14.             self.year -= 1

  15.         temp = self.year
  16.         self.year -= 1
  17.         return temp

  18.    
  19. leapYears = LeapYear()
  20. for i in leapYears:
  21.     if i >=2000:
  22.             print(i)
  23.     else:
  24.             break
复制代码




二、一个小技巧
重写__next__()函数的时候,可以先定义一个变量代表索引值,看需要而定,有时候需要一个始端,一个尾端。
在return之前,一定要先将返回值存入一个中间变量,再返回中间变量,这样可以对返回值进行操作,以便于下一次执行。

  1. class MyRev:

  2. ##    方法一
  3. ##    def __init__(self, arg = None):
  4. ##        self.arg = arg
  5. ##        self.index = 0
  6. ##        self.len = len(arg)
  7. ##        
  8. ##    def __iter__(self):
  9. ##        return reversed(self.arg)
  10. ##
  11. ##    def __next__(self):
  12. ##        if self.index < self.len:
  13. ##            val = self.age[self.index]
  14. ##            self.index += 1
  15. ##            return val
  16. ##        else:
  17. ##            raise StopIteration()

  18. ##     方法二
  19.     def __init__(self, arg = None):
  20.         self.arg = arg
  21.         self.index = len(arg) - 1

  22.     def __iter__(self):
  23.         return self

  24.     def __next__(self):
  25.         if self.index >= 0:
  26.             val = self.arg[self.index]
  27.             self.index -= 1
  28.             return val
  29.         else:
  30.             raise StopIteration()
复制代码



评分

参与人数 1荣誉 +5 鱼币 +1 贡献 +1 收起 理由
烽永力 + 5 + 1 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-15 17:51:24 | 显示全部楼层
对于你的第一段,我有深刻体会
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-15 17:56:53 | 显示全部楼层
蒋博文 发表于 2020-3-15 17:51
对于你的第一段,我有深刻体会

hhh,都是掉进过坑的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-15 18:05:37 | 显示全部楼层
看小甲鱼视频时:
眼:“嗯,我看懂了。”,耳朵:“嗯,我听懂了。”,脑子:“嗯,我理解了。”
自己写的时候:
手:“???”

哈哈哈哈哈
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-1 04:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表