python, twelve day

迭代器、生成器

生成器:就是自己python用代码写的迭代器,生成器的本质就是迭代器。

12l1 = [1,2,3]
iter1 = iter(l1)
用以下两种方式构建一个生成器
  1. 通过生成器函数。
  2. 生成器表达式。

函数:

12345def func1(x):
    x += 1
    return x
func1(5)    #函数的执行命令,并且接受函数的返回值。
print(func1(5))

生成器函数:

12345678910def func1(x):
    x += 1
    print(1)
    yield x
g_obj = func1(5)#生成器函数对象
print(g_obj)  #<generator object func1 at 0x000001AD4C6DC0F8>
print(g_obj.__next__())
print(g_obj.__next__())
#一个next 对应一个 yield
#yield 将值返回给   生成器对象.__next__()

yield ,return

return 结束函数,给函数的执行者返回值
yield 不会结束函数,一个next对应一个yield,给 生成器对象.__ next__()返回值。

生成器函数 vs 迭代器
1.自定制的区别
1234567891011def func1(x):
    x += 1
    yield x
    x += 3
    yield x
    x += 5
    yield x
g1 = func1(5)
print(g1.__next__())
print(g1.__next__())
print(g1.__next__())
区别:内存级别的区别。

迭代器是需要可迭代对象进行转化,可迭代对象非常占内存。
生成器直接创建,不需要转化,从本质就节省内存。

123456def func1(x):
    for i in renge(100000):
        yield i 
gl  = func1()
for i in range(50)
    print(g1.__next__())
send 与 next
123456789101112def func1():
    print(1)
    count = yield 6
    print(count)
    print(2)
    yield 7
    print(3)
    yield 8
g = func1():
print(next(g))
print(g.send('alex'))
print(next(g))
  1. send 与next一样,也是对生成器取值(执行一个yield)的方法。
  2. send 可以给上一个yield传值。
  3. 第一次取值永远都是next,最后一个yield 永远也得不到send传的值。
123456789101112#def cloth1(n):
#    for i in range(n+1):
#        print('衣服%s号' % i)
#cloth1(100000)
def cloth2(n):
    for i in range(1,n+1):
        yield '衣服%s号' % i
g = cloth2(10000)
for i in range(50):
    print(g.__next__())
for i in range(50):
    print(g.__next__())

列表推导式

一行代码几乎搞定你需要的任何的列表。

  1. 循环模式 变量(加工后的变量) for 变量 in iterable]
print([i for i in range(1,101)])
  1. 筛选模式
print([i for i in range(1,31)if i % 3 == 0])

优点:一行解决,方便。
缺点:容易着迷,不易排错,不能超过三次循环。
列表推导式不能解决所有列表的问题,所以不要太刻意用。

生成器表达式

将列表推导式的[]换成()即可。

g = (i for i in range(10000))
print(g.__next__())

生成器Generator:

  本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)

  特点:惰性运算,开发者自定义

猜你喜欢

转载自www.cnblogs.com/study-learning/p/9507598.html