zoukankan      html  css  js  c++  java
  • 迭代器、生成器、面向过程编程

    一、迭代器

    1.首先,器”,大家都已经了解,就是工具的意识,那么什么是迭代?

    迭代:“迭代是一个重复的过程,并且每次的重复都是基于上一次的结果而来的

    2.想要了解迭代器到底是什么?还必须先了解什么是“可迭代对象”?

    可迭代对象:在python中,但凡内置有_iter_方法的对象,都是可迭代对象

    例如以下都是可迭代对象

     str1='hello'
     list1=[1,2,3]
     tup1=(1,2,3)
     dic={'x':1}
     s1={'a','b','c'}
     f=open('a.txt','w',encoding='utf-8')

    3.迭代器

    定义:迭代取值工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象

    dic={'x':1,'y':2,'z':3}  # dic为可迭代对象
    iter_dic= dic.__iter__()  # iter_dic为迭代器对象
    print(iter_dic.__next__())
    print(iter_dic.__next__())
    print(iter_dic.__next__())
    
    打印结果:x y z 会将键值打印出来
    
    
    异常处理
    
    如果循环取值,但是本身的值并没有那么多会出现什么情况呢?
    当然会报错了,那么又有什么方法来控制呢
    x=[1,2,3]
    iter_x=x.__iter__()
    while True:
        try:  # try 就相当于与一个监督作用,如果取出的值超出了x的范围,那么就会停止取值
            print(iter_x.__next__())
        except StopIteration:
            break
    迭代器

    4.可迭代对象与迭代器的比较

    可迭代对象:

    str,list,dict,tuple,set,file

    获取可迭代对象方式:

    无需获取,python内置str,list,dict,tuple,set,file都是可迭代对象

    特点:

    内置有__iter__方法的都叫可迭代的对象,执行该方法会拿到一个迭代器对象

    迭代器对象:

    文件对象本身就是迭代器对象

    获取迭代器对象的方式:

    执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象

    特点:
    内置有__next__方法,执行该方法会拿到迭代器对象中的一个值
    内置有__iter__方法,执行该方法会拿到迭代器本身

    5.迭代器优缺缺点

    优点:

    1.>可以不按照索引取值

    因为它可以利用可迭代的对象执行__iter__方法直接得到的返回值

    2.>节省内存

    它可以将所有的值全部储存在一个空间,就是一个存储地址

    缺点:

    1.>取值麻烦

    因为它取值只能一个一个取,取完前面才能取后面

    2.>取值是一次性的,无法用len获取长度

    6.for 循环原理分析

    1.>for循环称之为迭代器循环,in后面跟的必须是可迭代对象

    2.>for循环会执行in后面对象的__iter__方法,转成迭代器对象

    3.>然后调用迭代器__next__方法,进行取值

    4.>依次循环,直到取值完毕,检测到异常StopIteration,自动结束循环

    二、生成器

    1.生成器

    生成器的本质就是迭代器

    函数内包含yield关键字,在调用函数,

    就不会执行函数体代码,拿到的返回值就是一个生成器

    如果取值范围超过本身的数值范围会怎样呢?

    既然会出现这种报错的情况,那么自然就有解决的方法

    yield即可以返回一个值,也可以返回多个值,

    并且多个值是以元组的形式返回,

    如果yield后面没有数值,那么就会返回None

    def func():
        print('=====>first')
        yield 1
        print('=====>second')
        yield 2
        print('=====>third')
        yield 3,4
        print('=====>forth')
        yield
    
    s = func()
    print(s)
    print(s.__next__())
    print(s.__next__())
    print(s.__next__())
    print(s.__next__())
    
    #  打印结果:
    =====>first
    1
    =====>second
    2
    =====>third
    (3, 4)
    =====>forth
    None
    View Code

     

    2.练习1:

    自定义range功能

     需要取出range里的值
     平常是使用for循环来取值
    for i in range(1,10):
        print(i)  # 打印结果:1~9的值
     这样就可以将其中的值全部取出,那么自定义生成器怎么取呢?
    def my_range(start,end,step=1):
        while start < end:
            yield start
            start += step
    for i in my_range(1,10):
        print(i)  # 打印结果:1~9的值
    View Code

     3.yield表达形式

    def eat(name):
        print('%s ready to eat' %name)
        food_list=[]
        while True:
            food=yield food_list # food='骨头'
            food_list.append(food) #food_list=['泔水','骨头']
            print('%s start to eat %s' %(name,food))
    
    
    dog1=eat('jack')
    
    1、必须初始化一次,让函数停在yield的位置
    res0=dog1.__next__()
    print(res0)
    
    2、接下来的事,就是喂狗
    send有两方面的功能
    1、给yield传值
    2、同__next__的功能
    res1=dog1.send('泔水')
    print(res1)
    res2=dog1.send('骨头')
    print(res2)
    res3=dog1.send('shit')
    print(res3)
    yield的表达形式

    4.yield与returnd的区别

    yield

    1.>会提供一种自定义生成的方式

    2.>会将函数的运行状态暂时停住

    3.>可以返回值,并且可以返回多个

    4.>可以接受外部传入的值

    return

    1.>可以返回值,并且可以返回多个

    2.>返回值后会将函数立即结束

    5.生成器表达式

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

    6.练习2:

    def add(n,i):
        return n+i
    def test():
        for i in range(4):
            yield i
    g=test()
    
    for n in [1,10]:
        g=(add(n,i) for i in g)
        # 第一次for循环g=(add(n,i) for i in test())
    
        # 第二次for循环g=(add(n,i) for i in (add(n,i) for i in test()))
    print(n)
    res=list(g)
    
    """
    for i in (add(10,i) for i in test()):  会执行所有的生成器内部的代码
        add(n,i)
    """
    View Code

    三、常用内置函数方法

    1.abs()  # 求绝对值
    2.all() # 只要有一个为False就返回False
    3.any() # 只要有一个位True就返回True
    4.callabe() # 可调用的
    5.chr() # 将数字转换成ascii码表对应的字符
    6.ord() # 将字符按照ascii表转成对应的数字
    7.dir() # 获取当前对象名称空间里面的名字
    8.divmod() # 分页器
    9.enumerate() # 枚举
    10.eval() # 不支持逻辑代码,只支持一些简单的python代码
    11.exec()
    12.format #三种玩法 #{}占位 {index} 索引 {name} 指名道姓
    13.isinstance # 后面统一改方法判断对象是否属于某个数据类型

    四、面向过程编程

    1.定义

    核心是'过程'二字,过程即解决问题的步骤,即先干什么,再干什么。。。。
    基于面向过程编写程序就好比在设计一条流水线,是一种机械式的思维方式。

    2.优缺点

    优点:
    将复杂的问题流程化 从而简单化
    缺点:
    可扩展性较差 一旦需要修改 整体都会受到影响

    3.示范

    #1、步骤一:拿到用户输入的合法的信息:用户名、密码、余额、年龄
    db_path='db.txt'
    
    def get_uname():
        while True:
            uname=input('用户名>>:').strip()
            if not uname.isalpha():
                print('33[45m用户名必须为英文字母...33[0m')
                continue
            with open(r'%s' %db_path,'r',encoding='utf-8') as f:
                for line in f:
                    uinfo=line.strip('
    ').split(',')
                    if uname == uinfo[0]:
                        print('33[45m用户名已存在...33[0m')
                        break
                else:
                    return uname
    
    def get_pwd():
        while True:
            pwd1=input('请输入密码>>: ').strip()
            pwd2=input('再次输入密码>>: ').strip()
            if pwd1 == pwd2:
                return pwd1
            else:
                print('33[45m两次输入的密码不一致,请重新输入...33[0m')
    
    def get_bal():
        while True:
            bal=input('请输入余额: ').strip()
            if bal.isdigit():
                # bal=int(bal)
                return bal
            else:
                print('33[45m钱必须是数字,傻叉...33[0m')
    
    def get_age():
        pass
    
    #2、步骤二:写入文件
    def file_hanle(uname,pwd,bal,age):
        with open(r'%s' %db_path,'a',encoding='utf-8') as f:
            f.write('%s,%s,%s,%s
    ' %(uname,pwd,bal,age))
    
    # 注册功能
    def register():
        #步骤1:
        uname=get_uname() #拿到合法的用户名
        pwd=get_pwd() #拿到合法的密码
        bal=get_bal() #拿到合法的余额
        #步骤2:
        file_hanle(uname,pwd,bal) #写入文件
    示范
    
    
  • 相关阅读:
    hdu3487 Play with Chain
    poj3481
    [HNOI2002]营业额统计
    poj3468 A Simple Problem with Integers
    [NOI2004]郁闷的出纳员
    UVa1308 LA2572
    20130620
    poj3580
    20130618
    C++类模版学习笔记
  • 原文地址:https://www.cnblogs.com/xiongying4/p/11185608.html
Copyright © 2011-2022 走看看