迭代器 生成器 函数递归

函数的进阶二

isinstance 方法

lis = [1,2]
print(isinstance(lis,Iterable)) # True
print(isinstance(lis,list)) # True
print(isinstance(rang(10),Iterable)) # True

1. 迭代器(不是函数,只是一个称呼而已)

1. 可迭代对象

  • 什么叫可迭代对象:

    只含有 .__iter__ 方法的数据类型就叫做可迭代对象 
    
  • 数据类型中除了数字类型之外,其他的都是可迭代对象

  • 可迭代对象使用 __iter__,就可以让可迭代对象变成迭代器对象
    dic = {'a': 1, 'b': 2, 'c': 3}
    dic1 = dic.__iter__()   #将可迭代对象变成迭代器对象
    #迭代取值:
    print(dic1.__next__())  # a
    print(dic1.__next__())  # b
    print(dic1.__next__())  # c
    # 载往下就会报错,因为已经将dic_iter 的值取完了
    而在迭代器对象后面加上 .__iter__() ,迭代器对象没有任何变化
    
    
    

2.迭代器对象

  • 什么叫迭代器对象

    含有 __iter__  和 __next__ 方法的对象就是迭代器对象
    
  • 只有文件是迭代器对象

    迭代器使用 __iter__ ,依然是迭代器
    
  • 为什么要有迭代器对象

    提供了 不依赖索引取值的手段

  • for 循环的原理(for 循环本质就是一个while循环,只不过是一个一定可控的while循环)

    # for 循环原理
    dic = {'a': 1, 'b': 2, 'c': 3}
    def for1(iterable):
        dic_iter = dic.__iter__()
        while True:
            try:
                print(dic_iter.__next__())
            except StopIteration:
                break
    for1(dic)
    
  • 可迭代对象不一定是迭代器对象;迭代器对象一定是可迭代对象

2. 三元表达式

# 比较大小
x = 10
y = 20
print(x) if x > y else print(y)

3. 字典生成式

1. for 循环生成字典

#生成字典
dic = {}
dic = {i:i**2 for i in rang(6)} 
# for之前的内容可以进行运算,for之后的格式不能变
print(dic) #{0:0,1:1,2:4,3:9,4:16,5:25}

2. zip 拉链

# 1. zip  方法的使用方法
res = zip([1,2,3],['a','b','c','d'],'4567896635')
# zip() 方法中只能放置可迭代对象类型的数据
print(res) # <zip object at 0x000000000A000388> ,res是一个迭代器, res.__next__() 返回的是元组
print(res.__next__()) # (1,'a',4)
print(res.__next__()) # (2,'b',5)
print(res.__next__()) # (3,'c',6) 
print(res.__next__()) # 会报错,因为,zip方法是按照最短的一个长度进行取值

# 2. zip方法生成字典

lt1 = ['a', 'b', 'c']
lt2 = [1, 2, 3]

dic = {k: v ** 2 for k, v in zip(lt1, lt2)}
print(dic)

lt = list('abc')
print(lt)

4. 列表推导式

lis = [i for i in range(10)]
print(lis) # [0,1,2,3,4,5,6,7,8,9]
lis1 = [i*2 for i in range(10)]
print(lis1) # [0,2,4,6,8,10,12,14,16,18]

5. 生成器表达式

res = (i for i in range(10))
#这个res是个生成器
res = [i for i in range(10)]
#这个res是个列表
  • 生成器节省内存,就像老母鸡下蛋,需要的时候就拿一个。每次都是占用取的值的内存空间

  • 而列表直接是一筐鸡蛋,一次性把全部的值存储到内存

6. 生成器

  • generator(发电机、生成器的意思) 本质是一个迭代器 ———》生成器:本质就是迭代器。生成器就是自定义的一个迭代器

  • 含有yield 关键字的函数就叫做生成器

    yield 的特性:

    1. 暂停函数
    2. 通过next取值 ,一个 yield 相当于一个next
  • def ge():
        yield 3  # 一个yield相当于一个next; 暂停函数
        yield 4
    
    # print(ge())  # ge()得到一个生成器 --> 生成器本质是迭代器
    print(ge()) # <generator object ge at 0x0000000009F45990>
    print(ge().__next__()) # 3
    print(ge().__next__()) # 3
    print(ge().__next__()) # 3
    
    # 不能直接用ge().__next__()取值,因为每次调用都会重新得到一个生成器,这样就只能取到第一个值,即 3
    
    g = ge()  # 得到同一个生成器
    print(g) # <generator object ge at 0x0000000009F45990>
    print(g.__next__()) # 3
    print(g.__next__()) # 4
    print(g.__next__()) # 会报错,已经结束迭代
    

7.函数递归

  • 什么是函数递归

    函数内部直接调用函数本身

    # 递归:
    # 1. 函数内部调用函数自己
    # 2. 必须要有退出条件
    # 3. 递归必须要有规律
    
  • import sys
    sys.setrecursionlimit(10) #设置最大递归次数
    print(sys.getrecursionlimit())
    
  • 
    def a():
        x = 1
        print(x)
        a()
    a()
    
    #每一次递归,会不会结束函数?不会,并且每一次递归都会开辟内存空间,如果一直开辟内存就炸掉了,所以最多递归1000次左右
    
  • # 玉阳 20岁 ; 后面的同学大2岁,后面的后面的同学比后面的同学大2岁; 求第6位同学的年龄
    
    '''
    res = 30 
    res = 28 + 2
    res = 26 + 2 + 2
    res = 24 + 2 + 2 + 2
    res = 22 + 2 + 2 + 2 + 2
    res = 20 + 2 + 2 + 2 + 2 + 2
    res = 18 + 2 + 2 + 2 + 2 + 2 + 2
    '''
    
    def age(x):
        if x == 0:
            return 18
        x -= 1
        return age(x) + 2
    
    
    res = age(6)
    print(res)  # 32
    
原文地址:https://www.cnblogs.com/Mcoming/p/11578941.html