zoukankan      html  css  js  c++  java
  • python学习笔记之生成器和迭代器、内置函数

    • 生成器
    • 迭代器
    • 内置函数
    • 作业

    一、生成器

    1.1、列表生成器

    问题引入:看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],我要求你把列表里的每个值加1

    方案一:

    a = [1,3,4,6,7,7,8,9,11]
    
    for index,i in enumerate(a):
        a[index] +=1
    print(a)
    
    原值修改
    

    方案二:

    >>> a
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> a = map(lambda x:x+1, a)
    >>> a
    <map object at 0x101d2c630>
    >>> for i in a:print(i)
    ... 
    3
    5
    7
    9
    11
    
    

    方案三:列表生成器

    >>> a = [i+1 for i in range(10)]
    >>> a
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    1.2、为什么要有生成器呢?

    通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

    所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

    1.3、生成器如何创建

    方法一,直接把列表生成器的【】变成():

    >>> L = [x * x for x in range(10)]
    >>> L
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    >>> g = (x * x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x1022ef630>
    

    可以注意到的是,g不再是一个列表生成器,而是一个generator对象了!!!!

    方法二,除了改写列表生成器来构造generator对象之外,还可以用函数实现:

    只需要把print-->yield

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            print(b)
            a, b = b, a + b
            n = n + 1
        return 'done'
    ##################################################
    >>> fib(10)
    1
    1
    2
    3
    5
    8
    13
    21
    34
    55
    done
    ####################################################
    def fib(max):
        n,a,b = 0,0,1
        while n < max:
            #print(b)
            yield  b
            a,b = b,a+b
            n += 1
        return 'done'
    ###################################################
    >>> f = fib(6)
    >>> f
    <generator object fib at 0x104feaaa0>
    

    可以看到,函数实现的功能是一样的,就是把print-->yield之后,fib(6)就变成了一个generator对象了,而不是一个普通函数

    1.4、如何使用gengrator呢

    如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值:

     g = (x * x for x in range(10))
    >>> next(g)
    0
    >>> next(g)
    1
    >>> next(g)
    4
    >>> next(g)
    9
    >>> next(g)
    16
    >>> next(g)
    25
    >>> next(g)
    

    generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误

    我们创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误。

    >>> g = (x * x for x in range(10))
    >>> for n in g:
    ...     print(n)
    ... 
    0
    1
    4
    9
    16
    25
    36
    49
    64
    81

    1.5、总结+理解难点

    def fib(max):
        n,a,b = 0,0,1
        while n < max:
            #print(b)
            yield  b
            a,b = b,a+b
            n += 1
        return 'done'
    data = fib(10)
    print(data)
    
    print(data.__next__())
    print(data.__next__())
    print("干点别的事")
    print(data.__next__())
    print(data.__next__())
    print(data.__next__())
    print(data.__next__())
    print(data.__next__())
    
    ######################################
    #输出
    <generator object fib at 0x101be02b0>
    1
    1
    干点别的事
    2
    3
    5
    8
    13
    

    最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行在上面fib的例子,我们在循环过程中不断调用yield,就会不断中断

    二、迭代器

    • 凡是可作用于for循环的对象都是Iterable类型;

      凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列(生成器一定是迭代器);

      集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

    可以使用isinstance()判断一个对象是否是Iterable对象:

    >>> from collections import Iterable
    >>> isinstance([], Iterable)
    True
    >>> isinstance({}, Iterable)
    True
    >>> isinstance('abc', Iterable)
    True
    >>> isinstance((x for x in range(10)), Iterable)
    True
    >>> isinstance(100, Iterable)
    False
    

    可以使用isinstance()判断一个对象是否是Iterator对象:

    >>> from collections import Iterator
    >>> isinstance((x for x in range(10)), Iterator)
    True
    >>> isinstance([], Iterator)
    False
    >>> isinstance({}, Iterator)
    False
    >>> isinstance('abc', Iterator)
    

    listdictstrIterable变成Iterator可以使用iter()函数:

    >>> isinstance(iter([]), Iterator)
    True
    >>> isinstance(iter('abc'), Iterator)
    True

    三、内置函数

    四、作业

    作业需求:

    模拟实现一个ATM + 购物商城程序

    1. 额度 15000或自定义
    2. 实现购物商城,买东西加入 购物车,调用信用卡接口结账
    3. 可以提现,手续费5%
    4. 每月22号出账单,每月10号为还款日,过期未还,按欠款总额 万分之5 每日计息
    5. 支持多账户登录
    6. 支持账户间转账
    7. 记录每月日常消费流水
    8. 提供还款接口
    9. ATM记录操作日志 
    10. 提供管理接口,包括添加账户、用户额度,冻结账户等。。。
    11. 用户认证用装饰器
  • 相关阅读:
    【用程序思维学习英语】
    【python3】修饰器简单理解
    【FLASK】发送QQ邮件
    【FLASK】数据库迁移
    【python3】with的用法
    【flask】工厂函数和蓝本的作用
    使用Python中的xltpl模块填充excel表格模板文件
    Python添加excel表格的批注
    在原有表格基础上面进行添加内容修改格式等操作
    Python操作excel表格库的介绍
  • 原文地址:https://www.cnblogs.com/mesunyueru/p/8970949.html
Copyright © 2011-2022 走看看