Python基础知识之生成器

九、迭代器与生成器

(一)迭代器

1.可迭代器对象 iterable

(1)迭代--每一次对过程的重复,每一次迭代得到的结果会作为下一次迭代的初始值

(2)可迭代器对象--具有iter函数的对象

(3)语法

"""--创建:.
    class可迭代对象名称: 
        def__iter__(self):
            return迭代器
--使用:.
    for变量名in可迭代对象: #原理:迭代器 = 可迭代对象.__iter__()
        语句.
"""
"""面试题:
​
1.for循环的原理?
​
    
"""
#获取迭代器
it = list02.__iter__()
#循环获取下一个元素
while True:
    try:
        item = it.__next__()
        print(item)
    except Stopiteration:
        break
        #遇到异常停止迭代
"""     
2.可以被for的条件是什么?
答:有.__iter__()方法的容器
"""   
​
​
#练习
lists = ["林黛玉","贾元春","贾迎春","贾探春","贾惜春"]
iterable = lists.__iter__()  #获取迭代器对象
#循环获取下一个元素
while True:
    try:
        temp = iterable.__next__()
        print(temp)
    except Stopiteration:
        break #遇到异常停止迭代
​
#练习2
dicts = {"林黛玉":101,"贾元春":102,"贾迎春":103,"贾探春":104,"贾惜春":105}
iterable = dicts.__item__()
while True:
    try:
        temp = iterable.__next__()
        print(temp,dicts[temp])
    except StopIteration:
        break

2.迭代器对象 iterator

(1)可以被next()函数调用并返回下一个值得对象

(2)语法

class 迭代器类名:
    def __init__(self,聚合对象):
        self.聚合对象 = 聚合对象
    
    def __next__(self):
        if 没有元素:
            raise StopIteration
        return 聚合对象元素
​
    
#练习 学生管理器  记录了多个学生 迭代出学生
class StudentModel:
    def __init__(self,id,name,sex):
        pass
    
class StudentManager:
    def __init__(self):
        self.__list_stu = []
    def insert(self,stu):
        if isinstance(stu,StudentModel):
            self.__list_stu.append(stu)
        else:
            raise ValueError()
    def __item__(self):
        return StudentIterator(self.__list_stu) #1.返回迭代器
​
class StudentIterator:   #迭代器
    def __init__(self,lists):
        self.__lists = lists
        count = 0
    def __next__(self):
        if count<len(self.lists):
            temp =self.__lists[count]
            count += 1
            return temp
         else:
            raise StopIteration
       
       
        
    
stu = StudentModel()
stu1 = StudentModel()
stu2 = StudentModel()
manager = StudentManager()
manager.insert(stu)
manager.insert(stu1)
manager.insert(stu2)
​
print("--------------------------------")
#for item in manager:
iterable = manager.__iter__()#1.获取迭代器   
​
while True:
    try:
        temp = iterable.__next__()
        print(temp)
    except StopIteration:
        break
​
​

(二)生成器

1.构成 可迭代对象+迭代器

2.定义

next(循环)一次,计算一次,返回一次 ​ 动态提供数据的可迭代对象,节省内存空间

3.原理

"""
生成器语法:
def 函数():
​
    yield 数据
​
for item in 函数名():
    语句
"""
#1.定义Myrange类,实现range的功能   过渡版
class MyRange:
    def __init__(self,end):
        self.end = end
    def __item__(self):
        return RangeIterator(self.end)
​
class RangeIterator: #迭代器
    def __init__(self,end):
        self.__begin = 0
        self.__end = end
    def __next__(self):
        if self.__begin <self.__end:
            temp = self.__begin
            self.__begin += 1
            return temp
        else:
            raise StopIteration
#next一次,计算一次            
for i in MyRange(10):
    print(i)
    
    
#2.定义Myrange类,实现range的功能  升级过渡版 
class MyRange:
    def __init__(self,end):
        self.end = end
    def __item__(self):
        number = 0
        while number <self.end
        yield number        #自动生成迭代器   将下列代码改为迭代器模式
        number += 1
​
        
        
#3.终极版
def num(value):    #定义
  count = 0
  while count < value:
      yield count
    count += 1
    
    
for item in num(10):   #调用
  print(item,end="")
​
​
     
    
#练习 学生管理器  记录了多个学生 迭代出学生  用yield
class StudentModel:
    def __init__(self,id,name,sex):
        pass
    
class StudentManager:
    def __init__(self):
        self.__list_stu = []
    def insert(self,stu):
        if isinstance(stu,StudentModel):
            self.__list_stu.append(stu)
        else:
            raise ValueError()
    def __item__(self):
        #return StudentIterator(self.__list_stu) #1.返回迭代器
         """
        执行过程:
        1.调用当前方法,不执行(内部创建迭代器对象)
        2.调用__next__方法,方执行
        3.执行到yied语句,暂时离开
        4.再次调用__next__方法,继续执行
        5.重复3,4  直到最后
         """
        count = 0
        while count <len(self.__list_stu):
            yield self.__list_stu[count]  #用yield生成迭代器
            count += 1
​
#class StudentIterator:   #迭代器
#    def __init__(self,lists):
#        self.__lists = lists
#        count = 0
#    def __next__(self):
#        if count<len(self.lists):
#           temp =self.__lists[count]
#            count += 1
#            return temp
#         else:
#            raise StopIteration
       
       
        
    
stu = StudentModel()
stu1 = StudentModel()
stu2 = StudentModel()
manager = StudentManager()
manager.insert(stu)
manager.insert(stu1)
manager.insert(stu2)
​
print("--------------------------------")
#for item in manager:
iterable = manager.__iter__()#1.获取迭代器   
​
while True:
    try:
        temp = iterable.__next__()
        print(temp)
    except StopIteration:
        break
​
        
        
#练习 从列表找出所有偶数 
lists = [45,66,88,12,5,27]
def get_even_number(lists):
    for item in lists:
        if item %2 == 0:
            yield item
​
for item in get_even_number(lists):
    print(i)
    
#练习 定义一个生成器函数my_zip,
"""
list1 = ["林黛玉","薛宝钗"]
list2 = [102,103]
for item in zip(list1,list2): #zip 将多个列表的每个元素合并成一个元祖
    print(item)
"""
list1 = ["林黛玉","薛宝钗"]
list2 = [102,103] 
def my_zip(*args):
    for i in range(len(args[0])):
        yield (item[i] for item in args)
    
for item in my_zip(list1,list2):
    print(item)
    
  """
​
    yield作用:将下列代码改为迭代器模式的代码.
​
    生成迭代器代码的大致规则:
​
    1.将yield以前的语句定义在next方法中
​
    2.将yield后面的数据作为next方法返回值
​
​
​
    """
​

4.优缺点

优:节省内存 ​ 缺:不能使用索引、切片访问结果

5.惰性操作->立即操作

list_result=list(<生成器>)

6.表达式 ​ re = (item for item in list01 if type(item) == int)#生成器对象

for item in re:

print(item)

7.生成器与迭代器关系

class 可迭代关系:
​
    def __iter__():
​
        return 迭代器对象
​
class 迭代器:
​
    def __next__():
​
调用
​
for  in 
​
# 面试题:
​
# 请简述,生成器与迭代器
​
# 生成器 本质就是 迭代器 + 可迭代对象.
​
# 而可迭代对象就是为了可以迭代(for),而迭代的本质就是不断调用迭代器next方法.
​
# 生成器最重要的特点调用一次next,计算一次结果,返回一个数据,
​
# 这个过程称之为惰性操作/延迟操作.
​
# 在海量数据下,可以大量节省内存.
​
​
# 惰性操作 --> 立即操作(灵活获取结果)
​
# list(生成器)
​
​

十、软件开发的目录规范

项目文件夹

bin #存放可执行文件

start.py

conf #项目的配置文件 如数据库路径、日志路径

settings.py

db #数据库文件夹

lib #共享库,公用区 common.py

core #核心代码逻辑 core.py

log #日志文件夹

api #

api.py

run.py

setup.py

requirements.txt

README

注:

  • core/:存放业务逻辑相关代码

  • api/:存放接口文件,接口主要用于为业务逻辑提供数据操作。

  • db/:存放操作数据库相关文件,主要用于与数据库交互

  • lib/t:存故程序中常用的自定义模块

  • conf:存放配置文件

  • run.py:程序的启动文件,一般放在项目的根目录下,因为在运行时会默认将运行文件所在的文件夹作为sys.path的第一个路径,这样就省去了处理环境变量的步骤 . setup.py:安装、部署、打包的脚本。

  • requirements.txt:存放软件依赖的外部Python包列表。 -README:项目说明文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨非墨Lg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值