Python初学者第二十四天 函数进阶(3)生成器

24day

1、列表生成式:

循环模式:[变量(加工后的变量) for 变量 in iterable]

print([i for i in range(0,101,2)])
[1,4,9,16,25,36,49]
print([i*i for i in range(1,8)])
#['python1期', 'python2期', .....'python20期']
print(['python%s期'%i for i in range(1,21)])

筛选模式:[变量(加工后的变量) for 变量 in iterable if 条件]

[变量(加工后的变量) for 变量 in iterable if 条件]
print([i for i in range(1,31) if i % 3 == 0])
print([i for i in range(1,31) if i % 3 == 0])
30以内能被2整除的数的平方
print([ i*i for i in range(1,31) if i % 2 == 0])
[1,2,3,4,6,7,8]
print([i for i in range(1,9)if i != 5])
l1 = ['wusir','ba', 'aa' ,'alex']
过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
print([i.upper() for i in l1 if len(i) > 3])
['WUSIR','ALEX']
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
将列表中的至少含有两个'e'的人名留下来。
l1 = []   
for l in names:   #正常情况
    for name in l:
        if name.count('e') >= 2:
            l1.append(name)
print(l1)
print([j for i in names for j in i if j.count('e')==2])  #列表生成式


 

 1 >>> a = [i+1 for i in range(10)]
 2 >>> a
 3 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 4 >>> a = [i+1 for i in range(10)]
 5 >>> a
 6 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 7 >>> a = [i+1 for i in a]
 8 >>> a
 9 [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
10 >>> a = [i+1 for i in a]
11 >>> a
12 [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

通过列表生成式,我们可以直接创建一个列表

2、生成器:generator

生成器特性:

- 不占内存

- 只能向前,不能返回

- 当生成器达到要求会报错

创建generator,方法一:一个列表生成式的[]改成(),就创建了一个generator

>>> a3 = (i for i in range(5))
>>> a3
<generator object <genexpr> at 0x0000000001DF5BA0>
>>> next(a3)
0
>>> next(a3)
1
>>> next(a3)
2
>>> next(a3)
3
>>> next(a3)
4
>>> next(a3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

通过for循环来调用生成器

>>> a3 = (i for i in range(5))
>>> for i in a3:
...     print(i)
...
0
1
2
3
4

通过while循环来调生成器(跳出循环会报错)

>>> a3 = (i for i in range(5))
>>> while True:
...     next(a3)
...
0
1
2
3
4
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
StopIteration

方法二:使用yield创建生成器(一个函数中包含yield关键字,那么这个函数就不在是一个普通的函数,而是一个generator)

generator和函数不一样。函数是按顺序执行,遇到return语句或最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时会从上一次返回的yield语句处继续执行。

return VS yield 

return :返回并中止function

yield :返回数据,并冰冻当前的执行过程。next唤醒冻结的函数执行过程,直到遇到下一个yield

 1 def fib(max):
 2     n,a,b = 0,0,1
 3     while n < max:
 4         yield b   #把函数的执行过程冻结在这一步,并且把b的值,返回给外面的next
 5         print(b)
 6         a,b = b,a+b
 7         n += 1
 8     return 'done'
 9 
10 f = fib(10)
11 next(f)
12 next(f)
13 next(f)

 当函数里面存在同时存在yield和return时,return值无法返回

 1 def range2(n):
 2     count = 0
 3     while count < n:
 4         print('count',count)
 5         count += 1
 6         yield count
 7     return 33333
 8 
 9 new_range = range2(3)
10 n1 = next(new_range)
11 n2 = next(new_range)
12 n3 = next(new_range)
13 n4 = next(new_range)

#执行结果如下

Traceback (most recent call last):
count 0
count 1
count 2
File "D:/编辑的文本/生成器.py", line 27, in <module>
n4 = next(new_range)
StopIteration: 33333

 3、生成器send

 1 def range2(n):
 2     count = 0
 3     while count < n:
 4         print('count',count)
 5         count += 1
 6         sign = yield count
 7         print('sign',sign)
 8     return 33333
 9 
10 new_range = range2(3)
11 n1 = next(new_range)
12 new_range.send('stop')

#执行结果:

count 0
sign stop
count 1

send------>>>>a、唤醒并继续执行;b、发送一个信息到生成器内部;

 总结:

列表推导式 与生成器表达式区别;
1,列表推导式 一行搞定,构建简单。
2, 不能用debug排错,比较复杂的列表列表推导式不能推导出来。

生成器表达式:
1,循环模式。 (变量(加工后的变量) for 变量 in iterable)
(变量(加工后的变量) for 变量 in iterable if 条件)
1,一行搞定。
2,节省内存。
posted @ 2018-01-31 22:49  摩柯无良  阅读(139)  评论(0编辑  收藏  举报