迭代器与生成器

一.迭代器

1.什么是迭代器

迭代:更新换代的过程,前一次循环的终止条件是后一次循环的初始条件。

迭代器:迭代取值的过程。

2.为什么要用迭代器

迭代器提供了一种不依赖索引取值的方式

3.怎么用迭代器

可迭代对象(iterable) :有内置方法__iter__          ps:补充:针对双下线开头双下划线结尾的方法,推荐读:双下+方法名

基本类型中的可迭代对象有:str,tuple,list,dict,set和文件对象(文件对象本身就是一个迭代器对象)

str = "12123"
lis = [1,2,3,4,5]
tup = (1,2,3,4)
dic = { "stevin" : "male"}
se = { 1,2,3,4}
with open("a.txt", "at",encoding="utf-8") as f :
    print(f.__iter__())


print(str.__iter__())
print(lis.__iter__())
print(tup.__iter__())
print(dic.__iter__())
print(se.__iter__())
View Code

迭代器(iterator):具有内置方法__iter__   和__next__   .  ps:迭代器一定是可迭代对象,可迭代对象不一定是迭代器对象。

        同时具有内置方法__iter__方法和内置方法__next__的可迭代对象,可以通过__iter__方法得到就是该对象的迭代器对象

        迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身

迭代器的取值必须使用__next__

迭代器的特点:只能按照次序向后取值,不能后退。

迭代取值:
优点
1.不依赖于索引取值
2.内存中永远只占一份空间,不会导致内存溢出

缺点
1.不能够获取指定的元素
2.取完之后会报StopIteration错

异常处理:当迭代器中的值被取完后,再用__next__取值会报出StopIteration异常

解决方法: try : 报错语句

     except StopIteration : 捕获异常后的操作

l = [1,2,3,4]
l = l.__iter__()
while True :
    try:
        print(l.__next__())
    except StopIteration :
        break
View Code

二.for循环的本质

for循环内部的本质
1.将in后面的literable对象调用__iter__转换成迭代器对象
2.调用__next__迭代取值
3.内部有异常捕获StopIteration,当__next__执行报错时,自动结束循环

三.生成器

生成器:个人自定义的迭代器,生成器的本质就是迭代器(具有__iter__   和__next__两个内置方法)

生成器的定义与函数的定义类似,使用yield代替return来进行返回结果。

def func() :
    print("first")
    yield 111   #yield后面跟的是调用迭代器__next__方法返回的值
    print("second")
    yield 222,"aaaa","bbbb"
    print("third")
    yield 333
    print("fourth")
    yield 444

res = func() # 有yield函数名加(),不会让函数运行
# 而是生成器初始化,把函数变为迭代器对象。
print(res.__next__()) #返回一个值
print(res.__next__()) #以元祖的形式返回多个值
print(res.__next__())
View Code

yield外界传参

def dog (name) :
    print("%s 准备开吃" %name)
    while True:
        food = yield
        print('%s 吃了 %s' % (name, food))

g = dog('stevin')
g.__next__()     # 必须在运行代码yield时,才能进行传值
g.send('大骨头')  # 给yield左边的变量传参  触发了__next__方法
g.send('饺子')
g.send('饺子')
View Code

生成器表达式:

格式:(变量名 for 变量名  in 容器类型 if 判断条件)

with open("b.txt", "rt",encoding="utf-8") as f :
    res = (len(line) for line in f)   # 生成器表达式
    print(sum(res))
View Code

生成器不会主动执行任何一行代码,必须通过__next__触发代码的运行

yield
1.帮你提供了一种自定义生成器方式
2.会帮你将函数的运行状态暂停住
3.可以返回值

yield与return的异同点
相同点:都可以返回值,并且都可以返回多个
不同点:
yield可以返回多次值,而return只能返回一次函数立即结束
yield还可以接受外部传入的值

四.内置方法

print(abs(-13.24))  # abs 求绝对值

l = [1,1,0]
print(all(l))  # all 存在一个为False就返回False
print(any(l))  # any 任意一位为True就返回True

def index():

    username = '我是局部名称空间里面的username'
    print(locals())   # locals 返回当前所在区域存储的所有的名字
    print(globals())  # globals 无论在哪 返回的都是全局名称空间
index()

print(bin(10))  # bin 十进制转2进制
print(oct(10))  # oct 十进制转8进制
print(hex(10))  # hex 十进制转16进制
print(int('0b1010',2))  # 其他进制转十进制

print(bool(1))
print(bool(0)) # bool判断真假


s = 'hello你好'
print(s.encode('utf-8'))  # encode 编码
print(bytes(s,encoding='utf-8'))   # 字节流

def index():
    pass

print(callable(index))  # callable 可调用的(可以加括号执行相应功能的)


print(chr(65))  #  chr 将数字转换成ascii码表对应的字符
print(ord('A'))  # ord 将字符按照ascii表转成对应的数字


print(dir(range(12))) # dir 获取当前对象名称空间里面的名字




print(divmod(101,10))
total_num,more = divmod(900,11)
if more:
    total_num += 1
print('总页数:',total_num)#  divmod  分页器


l = ['a','b','c','d']
for i,j in enumerate(l,1):# enumerate 枚举
    print(i,j)

# eval  exec 执行字符串表达式

s1 = """
print(1 + 2)
for i in range(10):
    print(i)
"""
# eval(s1)
exec(s1)


name = 'jason'
s2 = """
name
"""
print(eval(s2))  # eval不支持逻辑代码,只支持一些简单的python代码


def login():
    """
    一起嗨皮
    :return:
    """
print(help(login))  # help 查看函数注释



print(isinstance("123",list))  # isinstance 判断对象是否属于某个数据类型

print(pow(2,3)) # 返回 x的y次方。


print(round(3.4))  # round 四舍五入,取整
View Code

五.面向过程编程

面向过程编程:类似与流程化设计
好处:
将复杂的问题简单化,流程化
坏处:
可扩展性较差 一旦需要修改 整体都会受到影响

六.面试题

def multipliers():

    return [lambda x : i*x for i in range(4)]

print([m(2) for m in multipliers()])

#  扩展版
def multipliers2():
    list1 = []
    for i in range(4):

        def func(x):
        #应该这么修改:def func(x, i=i):

            return x * i

        list1.append(func)

    return list1

print([m(2) for m in multipliers2()])
View Code
原文地址:https://www.cnblogs.com/Cpsyche/p/11192146.html