• python进行曲——迭代生成


    迭代器 - 概念

    可迭代协议 : 内部含有__iter__方法的值/变量都是可迭代的
    通过可迭代变成迭代器 : 可迭代变量.__iter__()返回一个迭代器
    迭代器协议 : 内部含有__iter__方法和__next__方法的值/变量都是迭代器
    迭代器的特点 :节省内存,惰性运算,一次性取值,只能按顺序取
    可迭代和迭代器的关系:
    所有的迭代器都是可迭代的,反之不成立
    迭代器是特殊的存在
    for循环和迭代器的关系:
    无论是可迭代的还是迭代器都可以被for循环
    如果直接循环迭代器,那么循环一次就没有了
    如果循环的非迭代器,那么每一次循环都相当于从头到尾的循环
    是因为在for循环中的所有非迭代器都会通过iter生成一个新的迭代器

    
    
    迭代器引用
    可迭代的/可迭代对象
    for i in 7:print(i)
    iterable 可迭代
    整数类型 是不可迭代的
    iter 迭代
    iterable 可迭代的

    dir函数查看一个数据类型内部含有哪些方法
    两边带着双下划线的方法叫做"魔术方法","双下方法","内置方法"
    这些方法都有一个特点:你可以调但是不需要你直接调用
    ret_lst = dir([]) # 内置函数
    print(ret_lst)
    ret_str = dir('') # 内置函数
    print(ret_str)
    ret_num = dir(123) # 整数的内部是不含有__iter__方法的
    print(ret_num)

    可迭代协议 -- 只要是含有'__iter__'方法的数据类型都是可迭代的
    是python规定的 : 可迭代类型 和 python语言之间的协议

    检测某个变量/值 是不是可迭代的呢?
    print('__iter__' in dir([]))
    print('__iter__' in dir(123))

    第二种检测方式
    from collections import Iterable
    print(isinstance([],Iterable)) # 内置函数,判断一个具体的值是不是某个数据类型的
    print(isinstance(123,Iterable)) # 内置函数,判断一个具体的值是不是某个数据类型的

    可以迭代的都可以使用for循环

    print('__inter__' in dir([]))
    print('__inter__' in dir(123))
    from collections import Iterable
    print(isinstance([],Iterable))
    print(isinstance(123,Iterable))
    什么是迭代器?
    l = [1,2,3,4]
    res = l.__iter__()
    print(res)
    list_iterator iterator迭代器
    dir(l)
    print(dir(res))
    res中 但是不在l中的所有方法
    print(set(dir(res))-set(dir(l)))
    {'__next__', '__setstate__', '__length_hint__'}
    迭代器中特有的方法,l中没有
    print(res.__length_hint__()) # 迭代器中有多少个元素
    for i in res:
    print(i)
    res.__setstate__(2) # 控制迭代器从哪儿开始迭代
    for i in res:
    print(i)
    print(res.__next__()) # 从迭代器中取下一个值
    print(res.__next__())
    print(res.__next__())
    print(res.__next__())
    print(res.__next__())

    for循环一个列表的时候必须用的
    __next__取下一个值

    迭代器协议 : 含有__next__和__iter__方法的变量/值都是迭代器

    迭代器的特点:
    具有next和iter方法
    通过一个next多次执行就可以获得所有这个容器中的值
    迭代器中的值只能取一次
    不取的时候值不出现

    for循环取值
    for循环内部的机制就是迭代器取值的机制
    在for循环执行的过程中 : 先把可迭代的变成一个迭代器,然后再从中一个一个的取值

    range生成的就是一个迭代器,创建这个迭代器并不会真的把迭代器中的所有数据一次性生成
    什么时候生成呢? 只有通过next取值的时候才会生成
    记住你要多少个值 ,当前该给你什么,并且记住我下一个该给你什么,下一个和当前这个数的关系

    f文件句柄
    f记住 当前读到哪个位置了

    a = list(range(1000000000))
    print(a)

    迭代器的作用就是节省内存,for循环就是利用了迭代器节省内存的特点来对python当中的变量来进行操作的


    l = [1,2,3,4]
    res1 = l.__iter__()
    res2 = l.__iter__()
    res1和res2都是迭代器
    是两个完全不同的迭代器

    for i in res1:
    print(i)
    print('------')
    for i in res1:
    print(i)
    print('^^^^^^')
    for i in l.__iter__():
    print(i)
    print('******')
    for i in l.__iter__():
    print(i)

    for i in l:
    print(i)
    for i in l:
    print(i)

    自己创建一个迭代器
    循环这个迭代器
    dic = {'k':'v','k2':'v2'}
    dic_iter = dic.__iter__()
    print(dic_iter)

    print(dic_iter.__next__())
    for k in dic_iter:
    print(k)

    自己创建多个迭代器 : 每次执行iter方法就创建一个迭代器,每个迭代器都只能取值一次
    循环这些迭代器
    iter1 = dic.__iter__()
    iter2 = dic.__iter__()

    用while循环实现一个for循环的功能(循环list/dict)
    l = [1,2,3,5,6,7,12,23,412]
    l_iter = l.__iter__()
    while True:
    try: # 要保护的代码
    print(l_iter.__next__())
    except StopIteration: # 要保护的代码中一旦出现了StopIteration错误,程序不报错,直接执行break
    print('报错啦')

    count = 0
    l_iter = l.__iter__()
    while count < len(l):
    print(l_iter.__next__())
    count += 1

    本质上for循环替我们做了上面程序的一系列操作:
    生成迭代器
    循环每一次对这个迭代器执行next
    并且到迭代器的最后就停止

    判断一个变量/值是否是迭代器的方法
    lst_iterator = [].__iter__()
    print('__iter__' in dir(lst_iterator))
    print('__next__' in dir(lst_iterator))
    print('__iter__' in dir(lst_iterator) and '__next__' in dir(lst_iterator))

    f是一个迭代器还是一个可迭代的
    range是一个迭代器还是一个可迭代的
    f = open('file')
    print('__iter__' in dir(f) and '__next__' in dir(f))

    a = range(10)
    print('__iter__' in dir(a))
    print('__iter__' in dir(a) and '__next__' in dir(a))

    第二种方法
    from collections import Iterator
    f = open('file')
    print(isinstance(f,Iterator))
    print(isinstance(range(10),Iterator))

    a = range(10)
    for i in a:
    print(i)
    for i in a:
    print(i)


    生成器概念

    python语言自带的
    生成器 : 程序员通过简单的函数就可以实现的
    def func():
    print('hello')
    yield 1

    g = func() # 调用"生成器函数"
    print(g) # g generator(生成器)
    调用就不会执行这个函数,而是返回一个生成器
    print(dir(g)) # g是一个迭代器
    所有的生成器都是迭代器

    a = g.__next__()
    print(a)

    def func():
    print('hello')
    yield 1
    print('world')
    yield 2

    g = func()
    a = g.__next__()
    print(a)
    b = g.__next__()
    print(b)
    yield关键字的特点: 可以记录当前函数中执行的位置,下一次继续执行
    next和yield是一对搭档 : next开始函数的执行 yield停止函数的执行




     

  • 相关阅读:
    洛谷P2062 分队问题
    bzoj1800 飞行棋
    UVA11100 The Trip, 2007
    UVA11134 Fabled Rooks
    每天一道博弈论之“威佐夫博弈”
    每天一道博弈论之“A game”(伪博弈
    每天一道博弈论之“谁能赢呢?”
    每天一道博弈论之“牛的数字游戏”
    每天一道博弈论之“E&D”
    每天一道博弈论之“巴什博弈”
  • 原文地址:https://www.cnblogs.com/Godisgirl/p/9916637.html
Copyright © 2020-2023  润新知