zoukankan      html  css  js  c++  java
  • 迭代器 生成器 可迭代对象 迭代器对象 常用内置函数

    迭代器

    什么是迭代器
    迭代,更新换代(重复)的过程,每次的迭代都必须基于上一次的结果
    迭代器:迭代取值的工具
    为什么要用迭代器
    迭代器给你提供了一种不依赖于索引取值的方式
    # 需要迭代取值的对象
    # 列表 字典 字符串 元组 集合
    n = 0
    while True:
        print(n)
    这里只是简单的重复   死循环 
    
    
    
    电脑不好的别轻易尝试啊
    冒牌迭代器
     重复的+每次迭代都是基于上一次的结果而来的
    l = [1,2,3,4]
    s = 'hello'
    n = 0
    while n < len(l):
        print(s[n])   # h e l l    输出四个数字为什么不输出o    看判断条件
        n += 1
    正牌迭代器

    可迭代对象


    只有内部有__iter__方法的就是可迭代对象

    在基本数据类型中可以迭代的对象有
    字符串 列表 tuple dict set 文件类型(文件类型本身就是迭代器对象)

    n = 1
    f = 1.11
    s = [1,2,3]
    d = {'name':'james','age':'22'}
    t = (1,2,3,4,5,6,)
    set1 = {1,2,3,4,56,7,7}
    file1 = open(r'E:程序第四周xxx.txt','w',encoding='utf-8')
    
    print(s.__iter__())  # <list_iterator object at 0x00000000027A3A20>
    print(d.__iter__())  # <dict_keyiterator object at 0x00000000024868B8>
    print(t.__iter__())  # <tuple_iterator object at 0x00000000027A3A20>
    print(set1.__iter__())  # <set_iterator object at 0x00000000027A93A8>
    print(file1.__iter__())  # <_io.TextIOWrapper name='E:\程序\第四周\xxx.txt' mode='w' encoding='utf-8'>
    
    
    说明这几种数据类型可以被迭代  那么也就是说可迭代对象执行内置的__iter__方法得到的就是该对象的迭代器对象
    迭代器取值
    迭代器对象(句点符)
    1 内置有__iter__方法
    2 内置有__next__方法
    PS 迭代器一定是可迭代对象
    但是可迭代对象不一定是迭代器对象
    迭代器取值特点:只能从前向后一次取值 不能倒着取值
     总结可迭代对象/迭代器对象
    可迭代对象,内置有__iter__方法
    迭代器对象,内置有__iter__ 和 __next__方法的

     迭代取值:
    优点
    1 可以不依靠索引取值
    2 内存内永远只有占用一份空间,不会导致内存溢出
    缺点
    1 因为不能依靠索引取值,所以不能获取指定的元素
    2 当取的元素多余原元素时候就会报StopIteration的错误

    生成器
    l = [1,2,3,4]
    生成一个迭代器
    iter_l = l.__iter__()   # 内置有__iter__方法    所以符合条件  就是一个迭代器对象
    进行对迭代器的取值 低啊用__next__
    print(iter_l.__next__())  # 1
    print(iter_l.__next__())  # 2
    print(iter_l.__next__())  # 3
    print(iter_l.__next__())  # 4
    print(iter_l.__next__())  # StopIteration    报这个错误  因为值已经取完了
    列表
    dic = {'name':'james','pwd':'123','hobby':'basketball'}
    将这个字典dic转换成迭代器对象
    iter_dic = dic.__iter__()
    接下来取值
    print(iter_dic.__next__())  # name
    print(iter_dic.__next__())  # pwd
    print(iter_dic.__next__())  # hobby
    print(iter_dic.__next__())  # StopIteration 又是这个错误 那说明字典中的key已经被我们取完了
    字典
    异常处理
    while
    True: try: print(iter_d.__next__()) except StopIteration: # print('老母猪生不动了') break 当在取值的时候如果报错信息是 StopIteration 那么pycharm就会提示你 然后结束循环取值

    for循环的本质

    # 用了这么久的for循环取值,一直不知道什么原理吧,那就来搂一眼
    # for 循环结构
    # for 变量名 in 一个可迭代对象 也就是说 for循环 后面的容器类型 必须是可迭代对象


    for循环本质:
    1 将in后面的容器类型调用__iter__转型成迭代器对象
    2 调用__next__方法依次取值
    3 内部有异常捕获 StopIteration 时候 __next__ 会自动循环结束 也就是错与元素个数时候会报StopIteration这个错


    生成器   本身就是一个迭代器   只不过是我们自己定义的迭代器
    那就自己定义一个
    def func():
        print('frist')  #frist
        yield  666  # 666
        print('second')  # second
        yield  777  # 777
        print('third')  # third
        yield  888  # 888
        print('forth')  # forth
        yield  # None
    
    # yield后面的就是在调用迭代器__next__方法    输出你可以得到的值
    # yield既可以返回一个值也可以返回多个值  多个值的返回类型是元组
    
    g = func()  # 现将生成器初始化:将函数变成迭代器
    print(g)  # 出来个老母猪    下面开始下仔仔
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    # print(g.__next__())  # StopIteration
    View Code
    自定义一个range函数
    print(range(10))  #   老母猪 range(0, 10)
    看一下range是这么工作的
    for i in range(10):
        print(i)
    
    
    def my_range(start, end, step=1):
        while start < end:
            yield start
            start += step
    
    
    for j in my_range(1, 100, 2):
        print(j)

    yield(纯了解)

    yield支持外界为其传参
    def dog(name):
    print('%s 准备开吃'%name)
    while True:
    food = yield
    print('%s 吃了 %s'%(name,food))
    def index():
    pass

    当函数内有yield关键字的时候,调用该函数不会执行函数体代码
    而是将函数变成生成器
    g = dog('egon')
    g.__next__() # 必须先将代码运行至yield 才能够为其传值
    g.send('狗不理包子') # 给yield左边的变量传参 触发了__next__方法
    g.send('饺子')


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

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

    生成器表达式
    # 生成器表达式
    res = (i for i in range(1,1000000) if i!= 4)  # 生成器表达式   有木有发现这个是按照推理应该是元组生成式  不不不   没有元组生成式
    print(res)    # <generator object <genexpr> at 0x00000000024ADDB0>    看来是个老母猪  所以又要让老母猪下崽崽了
    '''
    生成器不会主动的执任何一行代码
    必须通过__next__触发代码的运行
    '''
    print(res.__next__())  # 1
    print(res.__next__())  # 2
    print(res.__next__())  # 3
    print(res.__next__())  # 5

    常用的内置函数

    print(abs(-11.11))  # 11.11  求绝对值
    l = [0,1,0]
    print(all(l))  # False 只要有一个为False就返回False
    print(any(l))  # True 只要有一个位True就返回True
    def index():
    
        username = '我是局部名称空间里面的username'
        print(locals())  # 当前语句在哪个位置 就会返回哪个位置所存储的所有的名字
        print(globals())  # 无论在哪 查看的都是全局名称空间
    index()
    print(bin(10))  # 0b1010
    print(oct(10))  # 0o12
    print(hex(10))  # 0xa
    print(int('0b1010',2))  # 10
    
    print(bool(1))  # True
    print(bool(0))  # False
    
    
    s = 'hello'
    print(s.encode('utf-8'))  # b'hello'
    print(bytes(s,encoding='utf-8'))  # b'hello'
    
    # 可调用的(可以加括号执行相应功能的)
    l = [1,2,3]
    def index():
        pass
    print(callable(l))  # False
    print(callable(index))  # True
    
    
    
    
    
    print(chr(97))  # a 将数字转换成ascii码表对应的字符
    print(ord('a'))  # 97  将字符按照ascii表转成对应的数字
    
    
    dir获取当前对象名称空间里面的名字
    l = [1,2,3]
    print(dir(l))
    
    import test
    print(dir(test))
    print(test.name)
    
    divmod  分页器
    
    print(divmod(101,10))
    total_num,more = divmod(900,11)
    if more:
        total_num += 1
    print('总页数:',total_num)
    
    enumerate 枚举
    l = ['a','b']
    for i,j in enumerate(l,1):
        print(i,j)
    
    eval  exec
    s = """
    print('hello baby~')
    x = 1
    y = 2
    print(x + y)
    
    """
    eval(s)
    exec(s)
    
    eval不支持逻辑代码,只支持一些简单的python代码
    s1 = """
    print(1 + 2)
    for i in range(10):
        print(i)
    """
    eval(s1)
    exec(s1)
    
    
    name = 'jason'
    s2 = """
    name
    """
    print(eval(s2))
    
    format 三种玩法
    {}占位
    {index} 索引
    {name} 指名道姓
    
    print(globals())
    def login():
        """
        一起嗨皮
        :return:
        """
    print(help(login))
    
    isinstance 后面统一改方法判断对象是否属于某个数据类型
    n = 1
    print(type(n))
    print(isinstance(n,list))  # 判断对象是否属于某个数据类型
    
    print(pow(2,3))  # 8   2的3次方
    
    
    print(round(3.4))  # 四舍五入
    
    """
    面向对象需要学习的方法
    classmethod
    delattr
    getattr
    hasattr
    issubclass
    property
    repr
    setattr
    super
    staticmethod
    """
  • 相关阅读:
    c++ 在window下创建窗口的基本步骤
    visual studio 2015 安装MSDN全称Microsoft Developer Network 安装离线的MSDN
    interp1一维数据插值在matlab中的用法
    Win32控制台、Win32项目、MFC项目、CLR控制台、CLR空项目、空项目区别
    C# 中的延时的方法。
    C#入门——Console.Write()与Console.WriteLine()
    php发送短信验证码
    来自联想、百度的团队,带着颠覆的理想,做短信服务平台
    python发送短信验证码
    uperTextView-从未如此惊艳!一个超级的TextView
  • 原文地址:https://www.cnblogs.com/xuzhaolong/p/11190828.html
Copyright © 2011-2022 走看看