• 迭代器,生成器,函数递归与二分法



    1. 什么是迭代器
    什么是迭代?
    迭代是一个重复的过程,但是每次重复都是基于上一次重复的结果而继续
    #下列循环知识单纯的重复
    while True:
    print(1)

    # 基于索引的迭代取值
    l=['a','b','c']
    i=0

    while i < len(l):
    print(l[i])
    i+=1
    什么是迭代器?
    迭代取值的工具



    2. 为什么要用迭代器
    迭代器
    优点
    1. 提供一种不依赖索引的迭代取值方式
    2. 更节省内存
    缺点:
    1. 不如按照索引的取值方式灵活
    2. 取值一次性的,只能往后取,无法预测值的个数

    3. 如何用迭代器
    可迭代的对象:strlist upledictset文件对象
    但凡内置有__iter__方法的对象都称之为可迭代对象

    迭代器对象: 文件对象
    既内置有__iter__方法又内置有__next__方法的对象都称之为迭代器对象


    调用可迭代对象下__iter__方法,会有一个返回值,该返回值就是内置的迭代器对象


    s='abcdef'
    l=['a','b','c']
    d={'k1':111,'k2':222,'k3':333}

    iter_d=d.__iter__()
    # print(iter_d)

    try:
    print(iter_d.__next__())
    print(iter_d.__next__())
    print(iter_d.__next__())
    print(iter_d.__next__())
    except StopIteration:
    print('取值完毕')


    d={'k1':111,'k2':222,'k3':333}
    d={1,2,3,4,5}
    d=[1,2,3,4]

    iter_d=d.__iter__()
    iter_d=iter(d) #d.__iter__

    print(next(iter_d)) #iter_d.__next__()

    print(len(d))
    print(d.__len__())


    print(iter_d.__iter__().__iter__().__iter__() is iter_d)

    print(d.__iter__().__next__())
    print(d.__iter__().__next__())
    print(d.__iter__().__next__())



    while True:
    try:
    v=iter_d.__next__()
    print(v)
    except StopIteration:
    break

    print('第二次取值')

    iter_d=d.__iter__()
    while True:
    try:
    v=iter_d.__next__()
    print(v)
    except StopIteration:
    break


    for k in d:
    print(k)

    for循环的底层原理:
    1. 调用in后面那个值/对象的__iter__方法,拿到一个迭代器对象iter_obj
    2. 调用迭代器对象iter_obj.__next__()将得到的返回值赋值变量名k,循环往复直到取值完毕抛出异常StopIteration
    3. 捕捉异常结束循环







    生成器就是一种自定义的迭代器

    如何得到生成器?
    但凡函数内出现yield关键字,再去调用函数不会立即执行函数体代码,会得到一个返回值,该返回值就是生成器对象,即自定义的迭代器



    def func():
    print('first')
    yield 1
    print('second')
    yield 2
    print('third')
    yield 3


    g=func()
    # print(g)

    res1=next(g)
    print(res1)

    res2=next(g)
    print(res2)

    res3=next(g)
    print(res3)

    next(g)

    总结yield:
    1. 提供一种自定义迭代器的解决方案
    2. yield & return
    相同点: 都可以返回值,返回值没有类型限制个数限制
    不同点: return只能返回一次值,yield却可以让函数暂停在某一个位置,可以返回多次值



    def my_range(start,stop,step=1):
    while start < stop: # 5 < 5
    yield start # 3
    start+=step #start=5

    range(1,5,2) # 1 3
    for i in my_range(1,5000000000000000000000000000000000000000000,2): # 1 3
    print(i)








    1. 函数的递归调用:
    在调用一个函数的过程又直接或者间接地调用该函数本身,称之为递归调用

    递归必须满足两个条件:
    1. 每进入下一次递归调用,问题的规模都应该有所减少
    2. 递归必须有一个明确的结束条件
    以下递归只是单纯的重复,没有意义
    def func():
    print(1)
    print(2)
    print(3)
    func()

    func()

    def bar():
    print('from bar')
    foo()

    def foo():
    print('from foo')
    bar()

    foo()
    递归有两个明确的阶段:
    1. 回溯
    2. 递推



    age(5)=age(4)+2
    age(4)=age(3)+2
    age(3)=age(2)+2
    age(2)=age(1)+2
    age(1)=18

    age(n)=age(n-1)+2 # n > 1
    age(1)=18 # n = 1

    def age(n):
    if n == 1:
    return 18
    return age(n-1)+2

    print(age(5))

    def age(n):
    if n==1:
    return 18
    return age(n-1)+2
    print(age(5))



    l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]

    def func(list1):
    for item in list1:
    if type(item) is not list:
    print(item)
    else:
    # 如果是列表,应该...
    func(item)

    func(l)

    二分法:
    nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341]

    find_num=203
    for num in nums:
    if num == find_num:
    print('find it')
    break
    else:
    print('not exists')


    nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341]


    def foo(list1,num):
    print(list1)
    if len(list1) == 0:
    print('not exist')
    return
    new_num=len(list1) // 2
    if num > list1[new_num]:
    # in the right
    foo(list1[new_num + 1:],num)
    elif num < list1[new_num]:
    # in the left
    foo(list1[:new_num],num)
    else:
    print('find it')

    foo(nums,203)


  • 相关阅读:
    ActiveMQ, Qpid, HornetQ and RabbitMQ in Comparison
    AMQP与QPID简介
    设置JVM内存溢出时快照转存HeapDump到文件
    How to find configuration file MySQL uses?
    linux命令行模式下实现代理上网
    CAS分析——Core
    单点登录加验证码例子
    统一建模语言(UML) 版本 2.0
    UML 2中结构图的介绍
    如何更改 RSA 的语言设置
  • 原文地址:https://www.cnblogs.com/huangchaonan/p/10059638.html
Copyright © 2020-2023  润新知