FRI.迭代器

FRI.迭代器

迭代器

什么是迭代器
  • 迭代器是用来迭代取值的工具
  • 迭代就是一个重复的过程,但是每次重复都是基于上一次的结果进行,类似于汽车中期改款
    • 迭代器分为可迭代对象(Iterable Object)和迭代器对象(Iterator Object)
# 单纯的重复不叫迭代
while True:
    1 + 1
# 初识迭代操作
count = 1
while count < 5:
    print(count)
    count += 1
  • 优点
    • 找到一种通用的迭代取值的方案
    • 惰性计算,节省内存**(迭代器对象在未调用前,可以存放无穷个元素,也只占用代码空间,在调用__next__方法时才会逐个产生值)**
  • 缺点
    • 不能指定取值,只能依次取值
    • 迭代器对象是一次性的,一个迭代器对象取值完毕,则不能继续取值
可迭代对象
  • 一类是集合数据类型,如 list 、tuple 、dict 、set 、str、文件等
  • 一类是生成器,包括生成器和带 yield 的各类生成式。

这些可以直接作用于 for 循环的对象统称为可迭代对象

1. 'aaa'
2. [1,2]
3. (1,2)
4. {'1': 2}
5. {1,2}
6. open('a.txt',mode='wt')
  • 调用可迭代对象的__iter__会得到一个返回值,该返回值是迭代器对象
迭代器版本
1. 'aaa'.__iter__()
2. [1,2].__iter__()
3. (1,2).__iter__()
4. {'1': 2}.__iter__()
5. {1,2}.__iter__()
6. open('a.txt',mode='wt').__iter__()

# 可迭代对象通过__iter__()内置方法转变为迭代器版本,再通过__next__内置方法取值,但可迭代对象的迭代器版本 != 迭代器对象
  • 补充:可以使用 isinstance() 判断一个对象是否是__iter__对象
迭代器对象特点
open('a.txt',mode='wt').__iter__()/__next__()
- 内置__next__方法
- 内置__iter__方法
    - 返回其本身
    - 为了简化 for 循环设计
- **迭代器对象(Iterator)一定是可迭代对象**
- **可迭代对象(Iterable)不一定是迭代器对象**
for 循环原理
list = [1, 2, 3, 4]
# 调用 in 后面那个对象的__iter__内置方法,得到一个迭代器对象 iter_list
iter_list = iter(list)
# i = next(iter_list),然后运行循环体代码
while True:
    # 重复步骤 2,直到取完值,抛出异常,for 循环会自动捕捉异常并结束循环
    try:
        print(next(iter_list))
    except StopIteration:
        break
        
        
list = [1, 2, 3, 4]
# for 循环工作原理
# 调用 in 后面那个对象的__iter__内置方法,得到一个迭代器对象 iter_list
# i = next(iter_list),然后运行循环体代码
for i in list
    # 重复步骤 2,直到取完值,抛出异常,for 循环会自动捕捉异常并结束循环
    print(i)
  • 不管是迭代器对象还是可迭代对象,统一通过__iter__方法转化为可以使用__next__方法的迭代器版本
  • 文件既是可迭代对象,亦是迭代器对象

生成器(Genrator Object) – 自定义迭代器

def func():
	  print('one')
    yield 111
    print('two')
    yield 222
    print('three')
    yield 333
g = func()
res = next(g)  # one
print(res)  # 111

res = next(g)  # two
print(res)  # 222

res = next(g)  # three
print(res)  # 333
  • 函数内但凡出现 yield 关键字,在调用函数不会立即执行函数体代码,而会返回一个生成器对象,生成器对象本质就是一个自定义的迭代器对象
yield 与 return
  • 相同
    • 均为返回值,都可以返回任意类型、个数的值
  • 不同
    • return 只能返回一次值,函数立即结束
    • yield 可以返回多次值,yield 可以暂停函数的运行生成式

函数递归调用

什么是函数递归
  • 函数递归是函数嵌套的特殊格式,即在调用一个函数时,在内部调用了其自己(重复相同逻辑)
递归分为两个阶段
  • 回溯: 一层一层往下调用
  • 递推:一层一层往上退出结果
为什么要用递归
l = [1,[2,[3,[4,[5,[6]]]]]]

def cycle(l):
    for i in l:
        if type(item) is not list:
            print(item)
        else:
            cycle(item)
递归实现二分法
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

def search(m, n):
    print(n)
    if len(n) == 0:
        print("It's not exists")
    mid = len(n) // 2
    if n[mid] == m:
        print("Got it")
    elif n[mid] > m:
        """in the left"""
        n = n[:mid]
        search(m, n)
    else:
        """in the right"""
        n = n[mid + 1:]
        search(m, n)

serach(7, nums)

三元表达式

  • 条件成立时的返回值 + if + 条件 + else + 条件不成立时的返回值
res = 'ok' if 'a' == 'a' else 'no'
print(res)

生成式

列表生成式
  •   list = [expression for item1 in iterable1 if condition1]
    
1. 不带条件的列表生成式
l = []
for i in range(10):
    l.append(i)
    
l = ['ok' for i in range(10)]

2. 带条件的列表生成式
l = []
for i in range(10):
    if i > 3:
        l.append(i)

l = [i for i in range(10) if > 3]
字典生成式
dic = {'k%d' % i: i for i in range(10)}
print(dic)
# {'k0': 0, 'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4, 'k5': 5, 'k6': 6, 'k7': 7, 'k8': 8, 'k9': 9}
集合生成式
dic = { i for i in range(10)}
# {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
生成器表达式
generator = (i for i in range(5))
print(gererator)
# <generator object <genexpr> at 0x10f296900>
"元组即不可变列表,可以通过 'tuple + 列表生成式'快速生成,故而将此方法作为生成器表达式 "
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值