python — 生成器、推导式、递归

1 生成器(函数的变异)

判断一个函数是否是生成器函数:只需看函数内部是否有yield

# 生成器函数(内部是否包含yield)
def func():
    print('F1')
    yield 1
    print('F2')
    yield 2
    print('F3')
    yield 100
    print('F4')
# (只要有yield)函数内部代码不会执行,返回一个 生成器对象 。
v1 = func()
# 生成器是可以被for循环,一旦开始循环那么函数内部代码就会开始执行。
for item in v1:
    print(item)

循环流程:

    1. for循环开始第一次循环,先执行yield前面的代码,执行到yield时,返回yield的值给item并停止第一次循环。
    2. 第二次循环:从上次循环的yield后面开始执行代码,执行到第二个yield(yield2)时,返回yield2的值给item并停止第二次循环。
    3. 直到循环完所有的yield,循环自动终止
    def func():
        count = 1
        while True:
            yield count
            count += 1
    
    val = func()
    
    for item in val:
        print(item)

    总结:函数中如果存在yield,那么该函数就是一个生成器函数,调用生成器函数会返回一个生成器,生成器只有被for循环时,生成器函数内部的代码才会执行,每次循环都会获取yield返回的值。

    def func():
        count = 1
        while True:
            yield count
            count += 1
            if count == 100:
                return
    
    val = func()
    for item in val:
        print(item)

    示例:读文件

    def func():
        """
        分批去读取文件中的内容,将文件的内容返回给调用者。
        :return:
        """
        cursor = 0
        while True:
            f = open('db', 'r', encoding='utf-8')# 通过网络连接上redis
            # 代指   redis[0:10]
            f.seek(cursor)
            data_list =[]
            for i in range(10):
                line = f.readline()
                if not line:
                    return
                data_list.append(line)
            cursor = f.tell()
            f.close()  # 关闭与redis的连接
    
    
            for row in data_list:
                yield row
    
    
    for item in func():
        print(item)

    redis源码示例

    生成器作用:

    • 生成数据

    • 是一种特殊的迭代器

      def func():
          yield 1
          yield 2
          yield 3
      
      v = func()
      result = v.__next__()
      print(result)
      result = v.__next__()
      print(result)
      result = v.__next__()
      print(result)
      result = v.__next__()
      print(result)
    • 也是特殊的可迭代对象

      def func():
          yield 1
      
      v = func()
      result = v.__iter__()
      print(result)

    其他知识:

    • yeild from关键字 (从xxx中一点点获取)

      def base():
          yield 88
          yield 99
      
      def func():
          yield 1
          yield 2
          yield from base()   # 从base()中一点点获取
          yield 3
      
      result = func()
      
      for item in result:
          print(item)

    生成器的send方法

    def func():
        print(123)
        n = yield 'aaa'
        print('-->',n)
        yield 'bbb'
    
    g = func()
    print(g)
    n = next(g)
    print(n)
    print('-'*20)
    next(g)   # g.send('uysdfhfoiusyg')与next(g)的作用一样

    注意:

    • 1.生成器取一次就没有了,再次取时内部为空

    • 2.惰性运算 :不取不执行

      ret = filter(lambda n:n%3==0,range(10))
      # ret是迭代器
      print(len(list(ret)))   # 4  # list(ret) = [0,3,6,9]
      print(len(list(ret)))   # 0  # list(ret) = []

2 推导式

2.1 列表推导式

  • 1.目的

    方便的生成一个列表

  • 2.基本格式

    • 变量 = [for循环的变量 for循环一个可迭代对象]

    • v1 = [i for i in 可迭代对象 ]
      v2 = [i for i in 可迭代对象 if 条件 ] # 条件为true时才进行append

    • 练习

      v1 = [ i for i in 'alex' ]   # ['a','l','e','x']
      v2 = [i+100 for i in range(10)]   # [100,101,102,103,104,105,106,107,108,109]
      v3 = [99 if i>5 else 66  for i in range(10)]   # [66,66,66,66,66,66,99,99,99,99]
      
      def func():
          return 100
      v4 = [func for i in range(10)]   # [func,func,func,func,func,func,func,func,func,func,]
      
      v5 = [lambda : 100 for i in range(10)]   # [lambda : 100,lambda : 100,lambda : 100,lambda : 100,lambda : 100,lambda : 100,lambda : 100,lambda : 100,lambda : 100,lambda : 100]
      result = v5[9]()    # 100
      
      v6 = [lambda :i for i in range(10)]   # [lambda :i,lambda :i,lambda :i,lambda :i,lambda :i,lambda :i,lambda :i,lambda :i,lambda :i,lambda :i,]
      result = v6[5]()   # 9
      
      v7 = [lambda x:x*i for i in range(10)]
      # 1.请问 v7 是什么?
       v7 = [lambda x:x*i,lambda x:x*i,lambda x:x*i,lambda x:x*i,lambda x:x*i,lambda x:x*i,lambda x:x*i,lambda x:x*i,lambda x:x*i,lambda x:x*i,]
      # 2.请问 v7[0](2) 的结果是什么?    v7[0](2) = 18
      
      def num():
          return [lambda x:i*x for i in range(4)]
      # num() -> [函数,函数,函数,函数]
      print([ m(2) for m in num() ]) # [6,6,6,6]
      
      # ##################### 筛选 #########################
      v8 = [i for i in range(10) if i > 5]   # [6,7,8,9]

2.2 集合推导式

  • 1.目的

    方便的生成一个集合

  • 2.基本格式

    • 变量 = {for循环的变量 for循环一个可迭代对象}

    • v1 = { i for i in 可迭代对象 }
      v2 = { i for i in 可迭代对象 if 条件 } # 条件为true时才进行append

      v1 = { i for i in 'alex' }   # {'a','l','e','x'}

2.3 字典推导式

  • 1.目的

    方便的生成一个字典

  • 2.基本格式

    v1 = { 'k'+str(i):i for i in range(10) }
    #{'K0':0,'K1':1,'K2':2,'K3':3,'K4':4,'K5':5,'K6':6,'K7':7,'K8':8,'k9':9}
    
    v1 = { 'k':i for i in range(10) }   # {'k':9} #字典的键存在,则新值覆盖旧值,不存在则更新。

2.4 生成器推导式

# def func():
#     result = []
#     for i in range(10):
#         result.append(i)
#     return result
# v1 = func()
v1 = [i for i in range(10)] # 列表推导式,立即循环创建所有元素。
print(v1)

# def func():
#     for i in range(10):
#         yield i
# v2 = func()
v2 = (i for i in range(10)) # 生成器推导式,创建了一个生成器,内部循环为执行。
# 示例一
def func():
    result = []
    for i in range(10):
        result.append(i)
    return result
v1 = func()
for item in v1:
   print(item)

# 示例二
def func():
    for i in range(10):
        def f():
            return i
        yield f
v1 = func()
for item in v1:
    print(item())

# 示例三:
v1 = [i for i in range(10)] # 列表推导式,立即循环创建所有元素。
v2 = (lambda :i for i in range(10))
for item in v2:
    print(item())

3 递归

递归就是 函数自己调用自己(缺点:效率低)

python默认支持的递归最大数是1000次

def func():
    print(1)
    func()
    
func()
def func(i):
    print(i)
    func(i+1)
    
func(1)
def func(a,b):          # 只能递归1000次的斐波那契
    # 1
    # 1
    # 2
    # 3 
    # 5 
    print(b) 
    func(b,a+b)
    
func(0,1)
def func(a):
    if a == 5:
        return 100000
    result = func(a+1) + 10
    return result 

v = func(1)

1555402471461

# 递归的返回值
def func(a):
    if a == 5:
        return 100000
    result = func(a+1) + 10

v = func(1)
name = 'alex'
def func():
    def inner():
        print(name)
     return inner
v =func()

猜你喜欢

转载自www.cnblogs.com/yangjie0906/p/11215849.html