233倔强不秃 发表于 2020-3-15 17:24:25

迭代器的坑

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

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

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

2012
2008
2004
2000

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

class LeapYear:
   
    def __init__(self):
      
      self.year = 2020
   
    def __next__(self):
      if ((self.year%4 == 0 and self.year%100 != 0) or (self.year%400 == 0)):
            temp = self.year
            self.year -= 1
            return temp
      else:
            self.year -1
      

    def __iter__(self):
      return self

   
   
      

leapYears = LeapYear()
for i in leapYears:
    if i >=2000:
            print(i)
    else:
            break



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


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

import datetime as dt

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

    def __iter__(self):
      return self

    def isLeapYear(self, year):
      if ((year%4 == 0 and year%100 != 0) or (year % 400 == 0)):
            return True
      else:
            return False

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

      temp = self.year
      self.year -= 1
      return temp

   
leapYears = LeapYear()
for i in leapYears:
    if i >=2000:
            print(i)
    else:
            break




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

class MyRev:

##    方法一
##    def __init__(self, arg = None):
##      self.arg = arg
##      self.index = 0
##      self.len = len(arg)
##      
##    def __iter__(self):
##      return reversed(self.arg)
##
##    def __next__(self):
##      if self.index < self.len:
##            val = self.age
##            self.index += 1
##            return val
##      else:
##            raise StopIteration()

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

    def __iter__(self):
      return self

    def __next__(self):
      if self.index >= 0:
            val = self.arg
            self.index -= 1
            return val
      else:
            raise StopIteration()



蒋博文 发表于 2020-3-15 17:51:24

对于你的第一段,我有深刻体会

233倔强不秃 发表于 2020-3-15 17:56:53

蒋博文 发表于 2020-3-15 17:51
对于你的第一段,我有深刻体会

hhh,都是掉进过坑的{:10_262:}

wuqramy 发表于 2020-3-15 18:05:37


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

哈哈哈哈哈
页: [1]
查看完整版本: 迭代器的坑