码迷,mamicode.com
首页 > 其他好文 > 详细

迭代器、生成器

时间:2019-07-16 08:11:30      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:特点   code   odi   依次   异常   multi   针对   star   就是   

什么是迭代器?

迭代:更新换代的过程,也是一个重复的过程,每一次的迭代都必须基于上一次的结果(迭代与迭代之间必须要有关系)

迭代器:迭代取值的工具

为什么要用迭代器?

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

 

需要迭代取值的数据类型:字符串、列表、元组、字典、集合

l = [1,2,3,4]

n = 0 

while n < len(1):

    print(l[n])

    n += 1
#重复+,每次迭代都是基于上一次的结果而来的  

  

可迭代对象

只要内置有__iter__方法的都叫做可迭代对象

补充:针对双下划线开头双下划线结尾的方法,推荐读双下+方法名

基本数据类型中可迭代对象的:str、list、tuple、dict、set、

文件对象(执行内置的__iter__之后还是本身,没有任何变化),文件对象本身就是迭代器对象。

可迭代对象执行内置的__iter__方法得到就是该对象的迭代器对象

迭代器取值

迭代器对象:

1、内置有__iter__方法

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

2、内置有__next__方法

迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象

 

可迭代对象:内置有__iter__方法的

迭代器对象:既内只有__iter__也内置有__next__方法

迭代取值:

优点:

1、不依赖于索引取值

2、内存中永远只占一份空间,不会导致内存溢出

缺点:

1、不能够获取指定的元素

2、取完之后会报stopiteration

 

d = {‘name‘:‘moly‘,‘password‘,‘123‘,‘hobby‘:‘read‘
#将可迭代对象d转换成迭代器对象
iter_d = d.__iter__()
#迭代器对象的取值必须用__next__
print(iter_d.__next__())   #name
print(iter_d.__next__())   #password
print(iter_d.__next__())   #hobby
print(iter_d.__next__())   #取完了,报错StopIteration异常

迭代器取值的特点:只能往后依次取,不能后退。

 

for循环后面的in关键字,跟的是一个可迭代对象

for循环内部的本质

1、将in后面的对象调用__iter__转换成迭代器对象

2、调用__next__迭代取值

3、内部有异常捕获stopiterration,当__next__报这个错,自动结束循环

 

生成器

它的本质就是一个迭代器

yield:函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行

           后面跟的值就是调用迭代器__next__方法你能得到的值,它既可以返回一个值,也可以返回多个值,并且多个值也是按照元组的形式返回

当函数内有yield关键字的时候,调用该函数不会执行函数体代码,而是将函数变成生成器

def my_range(start,end,step):

    while start < end:

         yield start

        start += step

for i in my_range(1,10,2):

    print(j)    

 

yield和return

yield

1、帮你提供了一种自定义生成器方式

2、会帮你保存上一次函数调用的状态

3、可以返回值

与return之间的相同点

都可以返回值,并且都可以返回多个值

不同点:1.yield可以返回多次值,而return只能返回依次函数立即结束

              2、yield还可以接受外部传入的值

 

生成器表达式

res = (i for i in range(1,10) if i != 4)   #生成器表达式

print(res)

优点:只占一行空间

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

 

面向过程编程:就类似于设计一条流水线

好处:将复杂的问题流程化,从而简单化

坏处:可扩展性比较差,一旦需要修改,整体都会受到影响

 

 注册功能

技术图片
#1.获取用户输入
def get_info():
    while True:
        username = input(">>>:").strip()
        if not username.isalpha():   #判断字符串不能包含数字
            print(不能包含数字)
            continue
        password = input(>>>:).strip()
        confirm_password = input("confirm>>>:").strip()
        if password == confirm_password:
            d = {
                1:user
                2:admin

            }
            while True:
                print("""
                    1 普通用户
                    2 管理员
                """)
                choice = input(please choice user type toregister>>>:).strip()
                if choice not in d:continue
                user_type = d.get(choice)
                operate_data(username,password,user_type)
                break
        else:
            print(两次密码不一致)

    #处理用户信息
def operate_data(username,password,user_type):
    res = %s|%s|%s\n%(username,password,user_type)
    save_data(res,userinfo.txt)

    #存储到文件中
def save_data(res,file_name):
    with open(file_name,a,encoding=utf-8) as f:
        f.write(res)

def register():
    get_info()

register()
View Code
技术图片
请写出一下代码的执行结果并解释。

def multipliers():

    return [lambda x, i=i: i*x for i in range(4)]
    # 0, 1, 2, 3
    # [func(x): return 0*x, func(x): return 1*x,
    # func(x): return 2*x, func(x): return 3*x, ]

print([m(2) for m in multipliers()])  # [0, 2, 4, 6]

# [func(x): return 0*2, func(x): return 1*2,
# func(x): return 2*2, func(x): return 3*2, ]
# [0, 2, 4, 6]
# [6, 6, 6, 6]

# 闭包函数的延迟绑定
# 在内层函数执行时才会绑定变量i
def multipliers2():
    list1 = []
    for i in range(4):
        def func(x, i=i):  #定义函数
            return x * i
        list1.append(func)   #把函数名称传进去
    return list1
print([m(2) for m in multipliers2()])  # [0, 2, 4, 6]
View Code

 

迭代器、生成器

标签:特点   code   odi   依次   异常   multi   针对   star   就是   

原文地址:https://www.cnblogs.com/pangqian/p/11191321.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!