首页
学习
活动
专区
圈层
工具
发布
30 篇文章

五、python学习笔记-函数-生成器

代码语言:javascript
复制
# 列表生成式
"""
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
"""
# 示例1、通过列表生成式穿件列表
list1 = [x for x in range(1, 11)]
print(list1)

# 可以使用两层循环,生成全排列
list2 = [m + n for m in '123' for n in 'abc']
print(list2)

# 可以通过函数
def foo(n):
    return n + 2


list3 = [foo(x) for x in range(1, 11)]
print(list3)
代码语言:javascript
复制
# 生成器
"""
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
"""
# 示例1、一个简单的生成器
s = (x for x in range(1, 11))

# 打印类型
print(type(s))

# 生成器使用
"""
1、可以通过next方法从生成器中取值。
    每次调用next(),就计算出下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。
    取值方式有两种,next()或者obj.__next__(obj为生成器对象)。建议使用next()
    取值时只能一个一个取出,不能指定取出第几个值,也不能往回取值
2、实际上next()调用的就是生成器对象的__next__方法。有__next__方法的对象就是生成器
3、生成器可以使用for循环,生成器是可迭代对象
"""
# 示例2、取值
"""
1、取值超出生成器范围时会报错。
"""
print(s.__next__())
print(next(s))

# 示例3、for循环
for i in s:
    print(i)

# 生成器创建方式
"""
1、通过表达式
2、yield
    如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个生成器函数
3、函数执行到yield时,会跳出函数并返回yield值,下次执行时会从上次结束的位置继续执行
"""


# 示例3、通过yield创建生成器
def foo():
    print('ok 1')
    yield 1
    print('ok 2')
    yield 2
    print('ok 3')
    yield 3


g = foo()
print(type(g))

# 取值
for i in g:
    print(i)

# send
"""
1、send可以在取值的同时给函数中的yield传值
2、send给yield的值会被赋值给他前面的变量
3、第一次send前如果没有next(),只能传一个None(因为第一次执行函数不知道给谁赋值,无法进行赋值操作)。
    必须使用send(None)或者next()
4、以下面的示例来说,第一次使用send(None)或者netx,生成器函数yield返回一个1
    第二次使用send('abc'),生成器函数使用变量a接收参数'abc',然后第二个yield返回2
    如果第一次send发送了参数,没有变量来接收,所以报错
"""


# 示例4、使用send
def foo1():
    print('ok 1')
    a = yield 1
    print(a)
    yield 2


# 使用send
g1 = foo1()
print(g1.send(None))   # g1.send(None)等同于next(g1)
print(g1.send('abc'))
下一篇
举报
领券