python 学习笔记 生成器函数进阶 表达式 各种推导式

一、复习

# 迭代器和生成器
# 迭代器:
# 双下方法:很少直接调用的方法.一般情况下,是通过其他语法触发
# 可迭代的 ---- 可迭代协议 含有__iter__的方法 ('__iter__' in dir(对象))
# 可迭代的一定可以被for循环
# 迭代器协议:含有__iter__和__next__方法
# 迭代器一定可迭代,可迭代的通过调用__iter__()方法就能得到一个迭代器
# 迭代器的特点:
# 很方便使用,且只能取所有的数据取一次
# 节省内存空间


# 生成器
# 生成器的本质就是迭代器
# 生成器的表现形式
# 生成器函数
# 生成器表达式
# 生成器函数
# 含有yield关键字的函数就是生成器函数
# 每次调用__next__()方法的时候会取到一个值
# 直到取完最后一个,再执行__next__()会报错

# 写生成器实现:有一个文件,从文件里分段读取内容
# readline
# read(10)
# 在读出来的内容前面加上一个'***',再返回给调用者

def generator():
for i in range(20):
yield '娃哈哈%s'%i

g = generator() #调用生成器函数得到一个生成器
ret = list(g)
print(ret)

# ret = g.__next__() # 每一次执行g.__next__就是从生成器中取值,预示着生成器函数中的代码继续执行

# print(ret)
# num = 0
# for i in g:
# num += 1
# if num > 50:
# break
# print(i)

# 从生成器中取值的几个方法
# next
# for
# 数据类型的强制转换

二、生成器函数进阶
# def generator():
# print(123)
# yield 1
# print(456)
# yield 2
#
# g = generator()
# ret = g.__next__()
# print('***',ret)
# ret = g.__next__()
# print('***',ret)

# def generator():
# print(123)
# c = yield 1
# print('======',c)
# print(456)
# yield 2
#
# g = generator()
# ret = g.__next__()
# print('***',ret)
# ret = g.send('hello') #send的效果和next一样
# print('***',ret)


# send 获取下一个值的效果和next基本一致
# 只是在获取下一个值的时候,给上一个yield的位置传递数据
# 使用send的注意事项
#第一次使用生成器的时候,是用next获取下一个值
# 最后一个yield不能接收外面的值


# 例子:获取移动平均值
# 10 20 30 10
# 10 15 20 17.5

# def average():
# sum1 = 0
# count = 0
# avg = 0
# while 1:
# num = yield avg
# sum1 += num
# count += 1
# avg = sum1 / count
#
# avg_g = average()
# avg_g.__next__()
# ret = avg_g.send(10)
# print(ret)
# ret = avg_g.send(20)
# print(ret)
# ret = avg_g.send(30)
# print(ret)


# 生成器的装饰器
# def init(func):
# def inner(*args,**keargs):
# g = func(*args,**keargs)
# g.__next__()
# return g
# return inner
# @init
# def average():
# sum1 = 0
# count = 0
# avg = 0
# while 1:
# num = yield avg
# sum1 += num
# count += 1
# avg = sum1 / count
#
# avg_g = average()
# # avg_g.__next__()
# ret = avg_g.send(10)
# print(ret)
# ret = avg_g.send(20)
# print(ret)
# ret = avg_g.send(30)
# print(ret)

# Python3里yield form

# def generator():
# a = 'abcdef'
# b = '123456'
# for i in a:
# yield i
# for i in b:
# yield i
#
# g = generator()
# for i in g:
# print(i)

# def generator():
# a = 'abcdef'
# b = '123456'
# yield from a
# yield from b
#
# g = generator()
# for i in g:
# print(i)

# 小结
# send
# send的作用范围和next一模一样
# 第一次不能用send
# 函数中的最后一个yield不能接收新的值

# 计算移动平均值的例子
# 预激活生成器的装饰器的例子
# yield form

三、生成器的表达式

# 列表推导式
# egg_list = ['鸡蛋%s'%i for i in range(10)] #列表推导式
# print(egg_list)
# 相当于
# egg_list = []
# for i in range(10):
# egg_list.append('鸡蛋%s'%i)
#
# print(egg_list)

# print([i*i for i in range(10)])

# 生成器表达式
# g = (i for i in range(10)) #生成器
# print(g)
# for i in g:
# print(i)

# 两者的不同处
# 括号不一样
# 返回值不一样 ==不占用内存
#

# g = (i*i for i in range(10)) #生成器
# # 现在还没有执行
# for i in g: #每次取一次执行一次
# print(i)

四、各种推导式
# [每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型]  #遍历之后把挨个处理
# [满足条件的元素相关的操作 for 元素 in 可迭代的数据类型 if 元素相关的条件] #筛选功能

# 例子
# 1.30以内所有能被3整除的数
# ret = [i for i in range(10) if i%3 == 0]
# print(ret)

# 2.30以内所有能被3整除的数的平方
# ret = [i*i for i in range(10) if i%3 == 0]
# print(ret)

# 3.找到嵌套列表中名字含有两个‘e’的所有名字
# names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
# ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
#
# ret = [name for lst in names for name in lst if name.count('e') >= 2]
# print(ret)

# 字典推导式
# 例子:
# 1.将一个字典的key和value对调
# mcase = {'a': 10, 'b': 34}
# mcase_frequency = {mcase[k]:k for k in mcase}
# print(mcase_frequency)

# 2.合并大小写对应的value值,将k统一成小写
# mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
# mcase_frequency = {k.lower():mcase.get(k.lower(),0) + mcase.get(k.upper(),0) for k in mcase}
# print(mcase_frequency)

# 集合推导式
# 例:计算列表中每个值的平方,自带去重功能
# squared = {x**2 for x in [1,-1,2]}
# print(squared)

# ret = [(x,y) for x in range(5) if x%2==0 for y in range(5) if y %2==1]
# print(ret)






猜你喜欢

转载自www.cnblogs.com/xiuyou/p/11321767.html
今日推荐