生成器和推导式


1.生成器和生成器函数
生成器的本质就是迭代器
生成器的获取方式:
1.1 通过生成器函数
  1.2 通过生成器表达式创建生成器
  1.3 通过数据转换
生成器函数:
函数中包含了yield的就是生成器函数
def func():
   print("111")
   yield 222  
ret = func() print(ret)
结果:
<generator object func at 0x10567ff68>

生成器函数被执行,获取到的是生成器,而不是函数的执行


取值:
__next__()
def produce():
    """生产衣服"""
    for i in range(1,100001):
        yield "生产了第%s件衣服"%i
product_g
= produce() print(product_g.__next__()) #要一件衣服 print(product_g.__next__()) #再要一件衣服 print(product_g.__next__()) #再要一件衣服
...
# 最后一个yield之后再进行__next__()会报错
# yield 返回值,可以让函数分段执行
send(值) 可以让生成器乡下执行一次,给上一个yiled传一个值,第一个和最后一个不用传值(最后一个传值相当于又向下执行一次,下边没有了,所有会报错)
def func():
    print('钢铁侠')
    a = yield "11"
    print(a)
    print("蜘蛛侠")
    b = yield "22"
    print(b)
    print("煎饼侠")
    c = yield "33"
    print(c)
g = func()
print(g.__next__())
print(g.send(1))
print(g.send(2))
print(g.send(3))    # StopIteration
可以for循环
def produce():
    """生产衣服"""
    for i in range(1,100001):
        yield "生产了第%s件衣服"%i

product_g = produce()
for i in product_g:
    print(i)
list() tuple() set() 
def func():
    yield "钢铁侠"
    yield "蜘蛛侠"
    yield "煎饼侠"
    yield "绿巨人"

g = func() print(list(g))


生成器表达式:(结果 for 变量 in 可迭代对象 if 筛选)
g = (i for i in range(10))
print(list(g))

gen = ("我第%s次爱你" % i for i in  range(10))   #拿到内存地址
for i in  gen:  # 进行for循环拿到结果
    print(i)


# 生成器表达式也可以进行筛选:
 # 获取1-100内能被3整除的数
 gen = (i for i in range(1, 100) if i % 3 == 0)
 for num in gen:
     print(num)
 # 100以内能被3整除的数的平方
 gen = (i * i for i in range(100) if i % 3 == 0)
 for num in gen:
     print(num)
View Code
生成器表达式和推导式的区别:
  1. 推导式比较耗内存. 一次性加载. 生成器表达式几乎不占用内存. 使用的时候才分配和使用内存
  2. 得到的值不一样. 推导式得到的是一个结果. 生成器表达式获取的是一个生成器,通过for循环拿结果
深坑==> 生成器. 要值的时候才拿值
 
2.各种推导式
2.1 列表推导式 [结果 for 变量 in 可迭代对象 if 筛选]
# 生成列表里面装1-1000的数据
lst = []
for i in range(1,1001):
    lst.append(i)
print(lst)

# 列表推到式:最终给的是list列表
# 语法 [最终结果(变量)for 变量 in 可迭代对象]
lst= [i for i in range(1,1001)]
print(lst)

# 获取1-100能被3整除的数
lst = [i for i in range(1,101) if i%3 == 0]
print(lst)
# 100以内被3整除的平方
lst = [i**2 for i in range(1,101) if i%3 ==0 ]
print(lst)
# 寻找名字中带两个e的人的名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
print([name for lst in names for name in lst if name.count('e') == 2])
View Code
2.2 字典推导式   {结果 for 变量 in 可迭代对象 if 筛选} 结果=>key:value
dic = {"a":"b","c":"d"}
# 把字典中的key:value互换.
new_dic = {dic[key]:key for key in dic}
# 把循环完的key放到新列表value位置
print(new_dic)


lst1 = ["大娃","二娃","三娃","四娃","五娃","六娃","七娃"]
lst2 = ['力大无穷','千里眼顺风耳','钢筋铁骨','喷火','喷水','隐身','宝葫芦']
# 把组成一个字典lst1里的元素是key,lst2里的元素是value
dic = {lst1[i]:lst2[i] for i in range(len(lst1))}
# 索引长度都是一样不需要考虑那么多,只需要循环一个列表就可以了
print(dic)
View Code
2.3 集合推导式   {结果 for 变量 in 可迭代对象 if 筛选} 结果=>key
lst = ["马化腾", "马化腾", "王建忠", "张建忠", "张建忠", "张雪峰", "张雪峰"]
s = {i  for i in lst}    # 集合推倒式
print(s)
# 集合推导式可以帮我们直接⽣成⼀个集合. 集合的特点: ⽆序, 不重复. 所以集合推导式⾃带去重功能
View Code

 


总结: 推导式有, 列表推导式, 字典推导式, 集合推导式, 没有元组推导式
生成器表达式可以直接获取到生成器对象. 生成器对象可以直接进行for循环.
生成器具有 惰性机制.

def add(a,b):
    return a+ b

def test():
    for r_t in range(4):
        yield r_t
g = test()


for n in [2,10]:
    g = (add(n,i)for i in g)
print(list(g))
一道难度系数n*的题
友情提示: 惰性机制, 不到最后不会拿值 

 

posted @ 2018-07-19 19:50  一纸休书  阅读(245)  评论(0编辑  收藏  举报