生成器

初识生成器

生成器和迭代器实际功能上没有什么区别。最大的区别就是生成器是自己用python语言编写的。

生成器的构建方式

python主要通过三种方式来创建生成器:

  1. 通过生成器函数
  2. 通过生成器推导式
  3. python内置函数或者模块提供(其实1,3本质上差不多,都是通过函数的形式生成,只是通过1是自己写的生成器函数,3是python提供的生成器函数而已)

生成器函数

def cen():
    print(11)
    return 22
ret=cen()
print(ret)
结果:
11
12

将函数的return换成yield这样cen()就不是函数了,而是一个生成器函数

def cen():
    print(11)
    yield 22
ret=cen()
print(ret)
结果:<generator object cen at 0x000002301463DC00>

为什么在函数中添加了yield在调用函数的时候就发现结果不是我们预想的结果呢,是因为当我们调用函数的时候函数体里的代码会进行执行当执行到yield的关键字的时候,发现我们是想声明一个生成器.程序就会返回一个生成器给咱们。

那么生成器对象如何取值呢?

def cen():
    print(11)
    yield 22
ret=cen()
l=ret.__next__()
print(l)
结果:
11
22
def cen():
    print(11)
    yield 22
    print(33)
    yield 44
ret=cen()
l=ret.__next__()
print(l)
l1=ret.__next__()
print(l1)
l2=ret.__next__()
print(l2)
结果:
22
33
  File "E:/python 25姜会会/每日代码&笔记/day14/day14作业代码.py", line 11, in <module>
44
    l2=ret.__next__()
StopIteration

当程序运行到最后一个yield.那么后面继续运行next()程序会报错,一个yield对应一个next,next超过yield数量就会报错,与迭代器一样。

yield 与return的区别:

return一般在函数中只设置一个,他的作用是终止函数,并且给函数执行者返回值。

yield在生成器函数中可设置多个,他的作用是暂停函数,next会获取对应yield生成的元素。

举例

def cen():
    lst=[]
    for i in range(100):
        lst.append("你好"+str(i))

    return lst
e=cen()
print(e)
这个比较浪费空间,并且效率不高
def cen():
    for i in range(100):
        yield "你好"+str(i)
e=cen()
for i in range(10):
   print( e.__next__())
 结果:
 这里的是产生几个我用几个

生成器的的作用是节省空间

可迭代对象:

优点:list,tuple,str 节省时间,取值方便,使用灵活(具有自己的是有方法)

缺点:大量消耗内存

迭代器:

优点:节省空间

缺点:不能直接查看值,使用不灵活,消耗时间一次性不可逆

生成器:

优点:节省空间,可以自己定义

缺点:不能直接查看数据,消耗时间,一次性,不可逆行

生成器使用场景

1当文件或容器中的数据量较大时建议使用生成器

数据类型(python3:range()| python2:xrange())都是可迭代对象__iter__()
文件句柄是迭代器 __iter__()和__next__()

# 区别什么是迭代器,什么是生成器
    #迭代器的地址 <list_iterator object at 0x000000987B6E97F0>
    #生成器的地址 <generator object func at 0x00000087C2A10CA8>
# 没有send方法就是一个迭代器,具有send方法的就是一个生成器

dield from:将列表中的数据一个一个取出来

# def func():
#     def foo():
#         print(11)
#     lst = {"key":1,"key1":2}
#     yield foo
#
# print(func().__next__())

# def func():
#     lst = [1,2,3,45,6]
#     lst1 = ["alex","wusir","taibi","baoyuan"]
#     yield from lst
#     yield from lst1
#
# g = func()

# for i in g:
#     print(i)

# lst = [1,2,3,45,6]
# lst1 = ["alex","wusir","taibi","baoyuan"]

# for i in lst,lst1:
#     print(i)

# yield 将可迭代对象一次性返回
# yield from 将可迭代对象逐个返回

推导式

# 推导式

# lst = []
# for i in range(10):
#     lst.append(i)
# print(lst)

# 列表推导式
    # 普通循环
    # print([i for i in range(10)])
    # print([变量 for循环])

    # 筛选

    # lst = []
    # for i in range(10):
    #     if i % 2 == 0:
    #         lst.append(i)
    # print(lst)

    # 筛选模式
    # print([i for i in range(10) if i % 2 ==0])
    # print([i for i in range(10) if i > 2])
    # [加工后的变量 for循环 加工条件]

# 集合推导式:
    # 普通循环
    # print({i for i in range(10)})
    # {变量 for循环}
    # 筛选模式
    # print({i for i in range(10) if i % 2 == 1})
    # {加工后的变量 for循环 加工条件}

# 字典推导式:
    # 普通循环
    # print({i: i+1 for i in range(10)})
    # {键:值 for循环}
    # 筛选模式
    # print({i: i+1 for i in range(10) if i % 2 == 0})
    # {加工后的键:值 for循环 加工条件}

# 生成器推导式:
    # 普通模式
    # tu = (i for i in range(10))
#  ( 变量 for循环)
    # 筛选模式
    # tu = (i for i in range(10) if i > 5)
#   (加工后的变量 for循环 加工条件)
    # for i in tu:
    #     print(i)


内置函数(1)

这里要注意有的函数是不要使用的。

# a = "88 + 99"
# a = """
# def func():
#     print(111)
# func()
# """
# print(type(a))
# print(eval(a))  # 神器一
# exec(a)         # 神器二
# 注意:千万记住 禁止使用
# exec(input("请输入内容:"))


# print(hash("123"))
# print(hash(12))
# print(hash(-1))
# print(hash(-10))
# print(hash((2,1)))

# dic = {[1,2,3]:2}
# print(hash([1,2,3]))

# hash() 作用就是区分可变数据类型和不可变数据类型
# lst = [1,2,3]

# help(list)  查看帮助信息

# def func():
#     print(1)
# lst = [1,23,4,]
# print(callable(lst))   # 查看对象是否可调用

# print(int("010101",16))
# print(float(3))
# print(int(3))

# print(complex(20))  # 复数

# print(bin(100))  # 十进制转二进制
# print(oct(10))   # 十进制转八进制
# print(hex(17))   # 十进制转十六进制

# print(divmod(5,2))  # (商,余)

# print(round(3.534232,2))   # 保留小数位

# print(pow(2,2))  #幂 pow 两个参数是求幂
# print(pow(2,2,3))  #幂 pow 两个参数是求幂后的余


# s = "你好"
# s1 = bytes(s,encoding="utf-8")  # 将字符串进行编码
# print(str(s1,encoding="utf-8"))

# print(s.encode("utf-8"))

# print(ord("你"))   # 通过元素获取当前(unicode)表位的序号
# print(chr(20320))      # 通过表位序号查找元素

# a = 'alex'
# print(repr(a))   #查看你数据的原生态  -- 给程序员使用的
# print(a)         # 给用户使用的

# lst = [1,2,0,4,5]
# print(all(lst))     # 判断容器中的元素是否都位真  and

# lst = [1,2,3,0,1,23]  # 判断容器中的元素是否有一个为真
# print(any(lst))

# a = 10
# def func():
#     a = 1
#     print(locals())     #  查看当前空间变量
#     print(1)

# func()
# print(globals())        #  查看全局空间变量



这里是一些函数名使用题和生成器的例子

原文地址:https://www.cnblogs.com/python25/p/11402552.html