09 Python列表生成式 生成器

  • 列表生成式
array = [i*2 for i in range(10)]
=>[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

#相当于
a = []
for i in range(10):
	a.append(i*2)
	
#假设func存在
 [ func(i) for i in range(10)]
  • 生成器
    1.什么事生成器
    通过列表生成式,可以直接创建一个列表。由于内存的限制,列表的容量有限。如果列表元素过多,会占用很多的空间,如果仅仅只需要个别列表元素,那么后面绝大多数元素占用的空间会白白浪费。所以这时候我们就需要用到生成器(generator)
import time
def timer(funcType):
    def out_wrapper(func):
        def wrapper(*args, **kwargs):
            start = time.time()
            func(*args, **kwargs)
            end = time.time()
            print(funcType,":%s" % (end - start))
        return wrapper
    return out_wrapper
#没有使用生成器
@timer(funcType="Normal")
def func_normal():
    a = [i for i in range(50000000)]
    
# 生成器
@timer(funcType="Generator")
def func_generator():
    a = (i for i in range(50000000))
    print(a)

func_normal()
func_generator()
=>	Normal :4.411223411560059
	<generator object func_generator.<locals>.<genexpr> at 0x000001E9CC7F5CA8>
	Generator :0.0

由于5千万个元素过大,我们列表中的元素不打印了。当我们打印生成器的时候发现,生成器仅仅只是声明了一块地址,并没有生成列表。
生成器只在访问他的时候才会生成数据。而且生成器值记录当前的位置,并不会记录之前的位置,想要的得到下一个值我们用next()方法。

a = (i for i in range(5))#[0,1,2,3,4]
a.__next__()
a.__next__()
print(a.__next__()) #2

2.函数和生成器
利用函数和生成器生成一个斐波拉契数列(1,1,2,3,5,8,13,21,34…)

def fib(max):
	n, a, b = 0, 0, 1
	while n<max:
	print(b)
	a, b = b, a + b
	n = n+1

我们要将函数fib变为generator只需要将fib中的print改为yield。

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a,b = b, a+b
        n = n+1

print(fib(100))
f = fib(100)
f.__next__()
print("do something")
f.__next__()
print(f.__next__())

=>	<generator object fib at 0x000001E958E25CA8>
	print("do something")
	2

使用生成器时,可以在函数运行过程中做其他事情。
3.生成器并行
使用生产者消费者模型解释生成器并行:

import time
def consumer(name):
	print("%s 我准备吃饭了" %(name))
	while True:
		yield = food
		print("[%s]吃了菜品[%s]!" %(name,food))

def producer():
	custom1 = consumer("Custom1")
	custom2 = consumer("Custom2")
	custom1.__next__()
	custom2.__next__()
	for i in range(10):
		time.sleep(1)
		print("做了一道菜")
		custom1.send(i)
		custom2.send(i)

producer()

在这里生成器相当于C#中的ansy方法。方法send(i)相当于将参数传递给yield所指变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值