详解Python迭代器,生成器,装饰器

南笙酒味 提交于 2019-12-13 12:42:25

迭代器

  • 简介:迭代器是python里面可以记住遍历位置的对象,迭代器只能往前不能往后,使用iter()创建一个迭代器,使用next()返回一个迭代器里面的元素。
  • 应用场景:数列的数据规模巨大,或者数列有规律,但是通过列表推导式推导不出来
#!/usr/local/bin/python3
  import sys
  it = iter([1,32,43,2])
  while True:
           try:
                  print(next(it))
           except StopIteration:
                   sys.exit()

参考:
廖雪峰的迭代器教程
菜鸟教程:迭代器与生成器
Tyson Lee的博客:详解高阶函数,闭包,装饰器

生成器

  • 简介:在python里面使用了yield的函数称为生成器,生成器返回一个迭代器,在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。调用一个生成器函数,返回的是一个迭代器对象

应用场景:

  • 列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。
  • 如:仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
  • 如果列表元素按照某种算法推算出来,那我们就可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。
  • 简单一句话:我又想要得到庞大的数据,又想让它占用空间少,那就用生成器

例子:

#!/usr/bin/python3
 
import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

参考: 廖雪峰的生成器教程

装饰器

参考:
B站的视频教程
廖雪峰的装饰器教程
菜鸟教程装饰器
简介:装饰器可以在代码运行期间动态地增加函数的功能,当我们想要给多个函数增加相同的功能,一个一个地区修改这些函数效率很低,而且代码混乱,我们可以采用装饰器
看一个例子:

#!/usr/local/bin/python3
import time
def display_time(func):
        def wrapper():
                t1 = time.time()
                func()
                t2 = time.time()
                print(t2-t1)
        return wrapper
def is_Prime(num):
        if num < 2:
                return True
        elif num ==  2:  
                return False
        else:
                for i in (2,num):
                        if num % i == 0:
                                return False
                return True
@display_time
def find_Prime():
        for i in range(2,10000):
                if is_Prime(i):
                        print(i)
find_Prime()

但是如果我们的调用装饰器的函数里面要返回一个值的话,可以这样写,修改装饰器代码的第六行和加上第九行

#!/usr/local/bin/python3
import time
def display_time(func):
        def wrapper():
                t1 = time.time()
                result = func()
                t2 = time.time()
                print(t2-t1)
                return result
        return wrapper
def is_Prime(num):
        if num < 2:
                return True
        elif num ==  2:  
                return False
        else:
                for i in (2,num):
                        if num % i == 0:
                                return False
                return True
@display_time
def find_Prime():
        count = 0 
        for i in range(2,10000):
                if is_Prime(i):
                        count += 1
        return count

再进一步,如果我们要往装饰器里面传参数,比如我不一定是计算2到10000中的素数,我要计算2到n里面的素数,可以这样改写装饰器,在wrapper()改成wrapper(n),func()改成func(n)就行

def display_time(func):
       def wrapper(n):
               t1 = time.time()
               result = func(n)
               t2 = time.time()
               print(t2-t1)
               return result
       return wrapper
def is_Prime(num):
       if num < 2:
               return True
       elif num ==  2:  
               return False
       else:
               for i in (2,num):
                       if num % i == 0:
                               return False
               return True
@display_time
def find_Prime(n):
       count = 0 
       for i in range(2,n):
               if is_Prime(i):
                       count += 1
       return count
find_Prime(10000)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!