迭代器和生成器详解

python迭代器和生成器详解

一.迭代:


1.什么是迭代:

迭代就是对list,tuple等数据类型进行for…in循环,这种方式叫遍历,也就是迭代。


2.什么是迭代对象:

  • 可迭代对象就是从循环中依次取出来的对象。
  • 常见的可迭代对象有:list,tuple,string,dict,range
  • 常见的不可迭代的对象有:数字,布尔值
  • 检测是否是可迭代对象的方法:isinstance(list,Iterable)
from collections import Iterable
list = [1,3,54,6]
print(isinstance(list,Iterable))  # True

3.可迭代协议:

  • 可迭代协议就是内部实现了__iter__方法。其中__iter__方法就是一个迭代器,包含迭代器的对象就是可迭代对象。
  • 判断方法:使用dir()函数查看是否含有__iter__。
print(dir(list))

"""输出结果"""
"""
['__add__', '__class__', '__class_getitem__', '__contains__', 
'__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', 
'__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', 
'__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', 
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', 
'__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', 
'__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 
'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
"""

4.迭代器:

  • 迭代器作用:在进行遍历时,每每循环一次都会返回下一个数据,直到读完所有的数据为止。迭代器的作用就是记住访问到了第几条数据,以便于拿到下一条数据。
  • 迭代器的本质:就是把存储数据和遍历数据分开来。
  • 迭代器必须有__iter__和__next__方法。
  • 迭代器优点:节省内存。不依赖索引取值。惰性计算。
  • 迭代器的两种实现方法:
"""第一种方法"""
list = [1,3,54,6]
listiter = list.__iter__()
print(listiter.__next__())
print(listiter.__next__())
print(listiter.__next__())
"""
输出结果:
1
3
54
"""

""""第二种方法"""
list = [1,3,54,6]
listiter = iter(list)
print(next(listiter))
print(next(listiter))
"""
输出结果:
1
3
"""
  • 创建一个迭代器:
class iterclass():
    def __init__(self,list):
        self.list = list
        self.location = 0
    def __iter__(self):
        return self
    def __next__(self):
        # 判断当前位置是否小于列表的长度
        if self.location < len(self.list):
            item = self.list[self.location]
            self.location += 1
            return item
        else:
            raise StopIteration
list = [1,3,54,6]
iterc = iterclass(list)
print(iterc.__iter__(),"返回迭代器")
for i in iter(iterc):
    print(i,"取值---")

5.for循环在循环可迭代对象时,其内部活动:

  • 将可迭代对象转换为迭代器
  • 使用__next__方法,进行一个一个的取值
  • 捕获了StopIteration异常,取值到底之后自动结束
"""while循环实现for循环"""
list = [1,3,54,6]
listiter = iter(list)
while True:
    try:
        print(next(listiter))
    except StopIteration:
        break

二.生成器:


1.什么是生成器:

  • 本质:是一个迭代器,即生成器是一种特殊的迭代器。
  • 特点:惰性运算,开发者自定义。
  • 生成器函数:在生成器函数中,用yield语句而不是return语句,yield语句一次返回一个结果。在其中两个结果的中间,函数是挂起的状态,以便于下次从离开的地方开始执行而不是从头开始。
  • 生成器表达式:类似于列表推导式,但生成器是按需取结果,而不是一次性来构建一个结果列表。

2.生成器函数:

  • 带有yeild关键字的函数就是生成器函数,yield返回的不是一个具体的值,而是一个可迭代对象。不断获取可迭代对象的值会推动函数的执行,直到函数执行完毕。
  • yield和return:return执行代表着程序的结束。yield只能写在函数里,return和yield不能沟通使用。
  • 想要执行生成器函数,必须调用__next__()方法
def func():
    a = 1
    print("生成器---1")
    yield a
    b = 2
    print("生成器---2")
    yield b
fun = func()
print(fun)   #<generator object func at 0x0000024E026D89E0>  表示就是一个生成器  代表其内存地址
print(fun.__next__())    # 生成器---1   1
time.sleep(2)
print(fun.__next__())    # 生成器---2   2
fun = func()
print(fun.__next__())   # 0
print(fun.__next__())   # 1
print(fun.__next__())   # 2

num = 0
"""取前五十个值"""
for i in fun:
    print(i)
    num += 1
    if num ==50:
        break
"""接着再取五十个值"""
for i in fun:
    print(i)
    num += 1
    if num ==50:
        break

3.send()方法:

  • 和__next__()方法作用基本一致
  • 在获取下一个值的时候给上一个yield传递数据
  • 在第一次取值的时候,必须用__next__()
  • 如果是函数的最后一个yield是不能接收外部的值的

4.列表推导式和生成器表达式:

  • 只需要把列表推导式的[]换成()就变成了生成器表达式
  • 生成器表达式和列表推导式相较的优点在于节省内存
"""列表推导式"""
list1 = [i for i in range(1,11)]
print(list1)    # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

"""生成器表达式"""
list2 = (i for i in range(1,11))
print(list2)  # <generator object <genexpr> at 0x0000017B69C789E0>
print(list2.__next__())  # 1
print(list2.__next__())  # 2
print(list2.__next__())  # 3

"""用sum()和生成器表达式结合计算一系列的和"""
sum = sum(i*2 for i in range(4))
print(sum)  #2+4+6    12

三.扩展:


1.列表推导式:

"""循环其他可迭代对象"""
list1 = [i*3 for i in "循环其他可迭代对象"]
print(list1) # ['循循循', '环环环', '其其其', '他他他', '可可可', '迭迭迭', '代代代', '对对对', '象象象']

"""加入判断语句"""
list2 = [i for i in range(11) if i%2 is 0 and i != 0]    # 求出十以内的偶数
print(list2)    # [2, 4, 6, 8, 10]

"""循环嵌套列表,多个for循环"""
list = [[1,3,"d"],["f","l",9]]
list3 = [j for i in list for j in i]
print(list3)  # [1, 3, 'd', 'f', 'l', 9]

"""列表推导式的嵌套"""
list4 = [[i for i in range(j)] for j in range(11) if j % 2 == 0 and j != 0]   # 先循环后边  由外到里
print(list4)  # [[0, 1], [0, 1, 2, 3], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]

2.字典推导式:

"""利用健来构建value值"""
dict1  = {key:key * 2 for key in "heelo"}
print(dict1)  # {'h': 'hh', 'e': 'ee', 'l': 'll', 'o': 'oo'}

"""把原字典的键值调换"""
dict = {'h': 'hh', 'e': 'ee', 'l': 'll', 'o': 'oo'}
dict2 = {dict[key]:key for key in dict}
print(dict2)  # {'hh': 'h', 'ee': 'e', 'll': 'l', 'oo': 'o'}


"""把大写换为小写并合并大小写的value值"""
mcase = {'a': 11, 'b': 22, 'A': 33, 'Z': 44}
dict3 = {key.lower() : mcase.get(key.lower(),0)+mcase.get(key.upper(),0) for key in mcase.keys()}
print(dict3)  # {'a': 44, 'b': 22, 'z': 44}

3.集合推导式:

  • 自带去重功能
set1  = {key:key * 2 for key in "heeloo"}
print(set1)  # {'h': 'hh', 'e': 'ee', 'l': 'll', 'o': 'oo'}

set2 = {x**2 for x in {1,-1,2,-2,5}}
print(set2)  # {1, 4, 25}
  • 11
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值