python特训营-**常用设计模式**

课程目标

  1. 列表生成式
  2. 生成器
  3. 迭代器

列表生成式
• Python内置的非常简单却强大的可以用来创建list的生成式
• 快速的把字典内容转变成list

>>> d = {
    
    'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']

生成器
• 循环的过程中不断推算出后续的元素呢?这样就不必创建完整
的list,这种一边循环一边计算的机制,称为生成器:
generator
• 两种定义

  1. (列表生成式)
  2. 带yield的generator function
    L = [x * x for x in range(10)]
    print(L)
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    g = (x * x for x in range(10))
    print(L)
    <generator object at 0x1034dc667>

迭代器
• for循环可以应用下列类型:

  1. 集合数据类型,list,tuple,dict,set,str等
  2. generator ,生成器和带yield的generator function等 • 直接可作用于for循环的叫可迭代对象:Iterable
    • 直接可作用于next方法的叫可以生成器对象:Iterator
    • 生成器可以同时作用于for循环和next()函数,不断调用,
    直到抛出StopIteration错误
d = {
    
    'x': 'A', 'y': 'B', 'z': 'C' }
print([k+'=' + v for k,v in d.items()])

# 生成list,【1,2,3....10】

print(list(range(1,11)))

print([x*x for x in range(1,11)])

#'abc' ,'123' 输出a1a2a3,b1b2b3,c1c2c3

print([m+n for m in 'abc' for n in '123'])

# 把a.b.c的点进行筛除
print([m+n for m in 'a.b.c' for n in '123' if m!= '.'])

# 生成器

g = (x * x for x in range(10))
print(g)

#next 不知道有多少个元素
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

#yield
#斐波那契数列 1,1,2,3,5,8 后一个数等于前两个数的和
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a+b
        n = n + 1
    return 'done'

fib(6)

#输出关键字换成yield
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a+b
        n = n + 1
    return 'done'

g = fib(6)

print(next(g))
print(next(g))
print(next(g))

while True:
    try:
        x = next(g)
        print(x)
    except StopIteration as e:
        print('没有数据了',e.value)
        break

'''
    迭代器
'''

#判断一个对象是否可迭代

# from collections import Iterable
# print(isinstance([],Iterable))
# print(isinstance({},Iterable))
# print(isinstance('abc',Iterable))

#判断一个对象是否是生成器 Iterator

# from collections import Iterator
# print(isinstance([],Iterator))
# print(isinstance({},Iterator))
# print(isinstance('abc',Iterator))

from collections.abc import Iterator
print(isinstance(iter([]),Iterator))
print(isinstance(iter({
    
    }),Iterator))
print(isinstance(iter('abc'),Iterator))
# print(isinstance(iter(123),Iterator))

iter([])
``


作业
# 输出:
# [1]
# [1, 1]
# [1, 2, 1]
# [1, 3, 3, 1]
# [1, 4, 6, 4, 1]
n = 0
results = []
for t in triangles():
print(t)
results.append(t)
n = n + 1
if n == 10:
break
if results == [
[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1],
]:
print('测试通过!')
else:
print('测试失败!')


想了很久都没想出来,看了一下别人的写法是:

```python
def triangles():
    L=[1]
    while True:
        yield L
        #这是一个生成器
        L=[L[0]]+[L[t]+L[t+1] for t in range(len(L)-1)]+[L[-1]]

小结

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

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

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

猜你喜欢

转载自blog.csdn.net/weixin_42873348/article/details/107592610
今日推荐