小甲鱼零基础学习python_31 【python中魔法方法六:迭代器和生成器】

1. 迭代器

我们接触的迭代器通常指 序列:字符串 字典 列表 元组….迭代器可以理解为一个对数据的打包:


以下是几个迭代器的例子:

1.1.1 字符串的迭代:

for i in 'FISHC':
    print(i)

这里写图片描述

1.1.2 字典的迭代:(字典迭代器里取出来的是键值key)

links ={'yhr':'ysp has a daughter',
        'zwh':'zcg has a son',
        'zyc':'yhr and zwh has a son'}

for i in links:  #字典迭代器里取出来的是key
    print("%s%s"%(i, links[i]))

这里写图片描述

1.1.3 列表的迭代:

leibiao=[1,2,3,4,5]
for i in leibiao:
    print(i,end=' ')

这里写图片描述

1.1.4 元组的迭代:

yuanzu = ('a','b','c')
for i in yuanzu:
    print(i,end=' ')

这里写图片描述


1.2.1 迭代操作的两个bif:

iter() 得到容器对象的迭代器

next() 返回下一个值 如果没有下个值,就会抛出一个异常

string='yhr'
it=iter(string)
print(next(it))
print(next(it))
print(next(it))
# print(next(it))  #没有下个值,就会抛出一个StopIteration异常

这里写图片描述

那么我们对迭代器的for循环是不是可以由next和iter两个BIF实现呢?

for 循环的迭代器实现:

string = 'zwh'
it = iter(string)  #iter获取迭代器对象返回给it
while True:
    try:
        each = next(it)
    except StopIteration:  #没有next以后抛出stopIteration异常 捕捉异常 结束死循环
        break
    print(each)

这里写图片描述

1.2.2 两个魔法方法,注意不是BIF:

_ _ iter _ _() # 返回迭代器本身 return self

_ _ next _ _() # 决定了迭代器的迭代规则

例子:Fibonacci数列的实现:

class fibs:
    def __init__(self):
        self.a = 0

    def __iter__(self):
        print('iter......')
        return self

    def __next__(self):
        print('next.....,', end='  ')
        self.a , self.b = self.b, self.a+self.b
        return self.a

fib=fibs()
for each in fib:
    if each<20:
        print(each)
    else:
        break

这里写图片描述

迭代器可以没有终点的运行下去

那么怎么控制迭代范围呢?

由于For循环会自动处理stopIteraion的异常,所以可以在next里面设置抛出一个异常:


class fibs:
    def __init__(self,n=10):
        self.a = 0
        self.b = 1

    def __iter__(self):
        print('iter......')
        return self

    def __next__(self):
        print('next.....,', end='  ')
        self.a , self.b = self.b, self.a+self.b
        if(self.n<=0):
            raise StopIteration  #for 语句会处理StopIteration异常
        else:
            self.n-=1
            return self.a



fib=fibs()
for each in fib:
    print(each)

这里写图片描述


高铁上补笔记真的头昏眼花,先睡一觉再说吧咳咳咳


2. 生成器:

生成器 是迭代的一种方法,在普通的函数里加一个 yield 语句就可以实现生成器

模仿协同程序 ( 协同程序: 可以运行的独立函数调用,函数可以暂停或挂起,并在需要的时候从程序离开的地方继续或者重新开始 )

生成器是一个特殊的函数,调用可以中断或者暂停,并且通过yield返回固定的值。

Eg:

def myGen():
    print('生成器被执行!')
    yield 1  # 相当于return 但是和普通函数不同,仅仅是暂停,返回完参数就继续执行
    yield 2
myG = myGen()
print(next(myG))
print(next(myG))
# print(next(myG))   #StopIteration

这里写图片描述
倘若next里面没有值了,则会抛出stopIteration异常

for循环可以处理StopIteration异常,所以以上程序我们可用for循环来实现:

myG = myGen()
for i in myG:
    print(i)

这里写图片描述


例:Fibonacci数列的实现:

def fibs(countVal=5):
    a = 0
    b = 1
    count = countVal
    while True:  #死循环
        a , b = b , a+b
        yield (a)           # 每次yield都会暂停 返回一个a

        count -=1
        if(count<=0):
            break  #如果循环次数超过count(count默认为5)次,则跳出死循环
fib = fibs()
for i in fib:
    print(i, end=' ')

这里写图片描述


3. 补充:推导式:

3.1 列表推导式:

Eg:求100以内 可以被2 整除,不能被3整除的数字:
a = [i for i in range(100) if not(i%2) and i%3]
print(a)

这里写图片描述

3.2 字典推导式:(字典需要冒号,否则就是集合)

Eg:求10以内被2 整除的情况:
b={i:i%2==0 for i in range(10)}
print(b)

这里写图片描述

3.3 集合推导式:(字典需要冒号,集合不需要冒号)

Eg:找出一个列表里可以被2整除的数字,组成一个集合:
c={ i for i in [1, 2, 2, 2, 2, 3, 3, 3, 6] if i%2==0 }
print(c)

这里写图片描述

字符串和元组没有推导式!

比如假设元组存在推导式:

e=(i for i in range(3))
print(e)

3.4 其实是生成器推导式 generator object

这里写图片描述

3.4.1. 生成器对象可以用next读取:

print(next(e), end =' ')
print(next(e), end =' ')
print(next(e), end =' ')

3.4.2. 也可以用集成好的for循环读取生成器对象:

for each in e:
    print(each, end =' ')

这里写图片描述


3.5 生成器推导式甚至可以作为函数参数:

例如求和:把从0 开始小于10的数字不能整除2的数字相加:
e = (i for i in range(10) if i%2)
for each in e:
    print(each, end=' ')

print('\n',sum(i for i in range(10) if i%2))   #利用生成器对象作为函数参数

这里写图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值