python学习之路--day12迭代器与生成器

一、迭代器

1.什么是迭代器

迭代:一个重复的过程,但每次重复都是基于上一次重复的结果而继续

迭代器就是迭代取值的工具

2.为什么要用迭代器

对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器

优点:

I.其可以提供一种不依赖索引的迭代取值方式

II.更节省内存

缺点:

I.不如按照索引的取值方式灵活

II.其为取值一次性的,只能向后取,无法预测值的个数

可迭代对象:内置有__iter__方法的对象,即obj.__iter__(str\list\tuple\dict\set\文件对象)

迭代器对象:既内置有__iter__方法又内置有__next__方法的对象,即open('a.txt').__iter__(文件对象)

迭代器对象为可迭代对象执行obj.__iter__()得到的结果

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

迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象

3.如何用

dic={'a':1,'b':2,'c':3}

iter_dic=dic.__iter__() #得到迭代器对象,迭代器.__iter__()得到的仍然是迭代器本身
iter_d=iter(d) #其相当于d.__iter__

print(iter_dic.__next__())  #《==》next(iter_dic)
# 需注意,当next次数超过key次数时,会抛出StopIteration结束标志
while True:
    try:
        v=iter_d.__next__()
        print(v)
    except StopIteration:
        break
#a  b  c
View Code
dic={'a':1,'b':2,'c':3}
for k in dic:
    print(dic[k])   # 1  2  3 
  
for循环


for循环的底层原理
1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
2: 执行iter_obj.__next__()即next(iter_dic),将得到的值赋值给k,然后执行循环体代码
3: 重复过程2,直到捕捉到异常StopIteration,结束循环

二、生成器:一种自定义的迭代器

1.如何得到

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

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


g=func()
print(g)       # <generator object func at 0x0000025FB008FE08>
res1=next(g)   # first
print(res1)    # 1

res2=next(g)   # second
print(res2)    # 2

res3=next(g)   # third
print(res3)    # 3

next(g)        # StopIteration
View Code

yield:

1.提供一种自定义迭代器的解决方案

2.yield & return

相同:都可以返回值,返回值没有类型/个数限制

不同:return只能返回一次值,yield却可以让函数暂停在某一个位置,可以返回多次值

 三、函数的递归调用与二分法

 递归

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

递归必须满足两个条件:

I.每进入下一次递归调用,问题的规模都应该有所减少

II.递归必须有一个明确的结束条件‘

递归有两个明确的阶段

I.回溯 :一层一层地递归调用下去

II.递推 :在某一层结束掉递归,然后一层一层返回

2.为何用

在某些情况下,基于递归来使用重复的过程比while循环更简单

 3.如何用

一个嵌套很多层的列表,用递归取出所有的值
l = [1, [2, [3, [4, [5, [6, [7, [8, ]]]]]]]]

def func1(listl):
    for item in listl:
        if type(item) is not list:
            print(item)
        else:
            func1(item)

func1(l)

#or
def get(seq):
    for item in seq:
        if type(item) is list:
            get(item)
        else:
            print(item)
get(l)
一个嵌套很多层的列表,用递归取出所有的值

二分法

二分法是算法的一种,算法是如何高效地解决问题的思路

nums = [1, 13, 15, 23, 27, 31, 33, 57, 73, 81, 93, 94, 97, 101]  # 从小到大排列的数字列表
def binary_search(find_num,nums):
    print(nums)
    if len(nums) == 0:
        print('not exists')
        return
    # 功能
    mid_index = len(nums) // 2
    if find_num > nums[mid_index]:
        # in the right
        nums=nums[mid_index+1:]
        # 重新运行功能,传入新列表
        binary_search(find_num,nums)
    elif find_num < nums[mid_index]:
        # in the left
        nums=nums[:mid_index]
        # 重新运行功能,传入新列表
        binary_search(find_num,nums)
    else:
        print('find it')

# binary_search(97,nums)
binary_search(95,nums)
View Code

猜你喜欢

转载自www.cnblogs.com/dongzhihaoya/p/10059396.html