python学习day14 生成器表达式

# 迭代器和生成器

# 迭代器:
# 双下方法:很少用 ,一般是通过其他方法触发的
# 可迭代协议——含有__iter__方法
# 迭代器协议——含有__iter__和__next__方法
# 可迭代的一定可以for循环
# 迭代器一定可迭代,可迭代对象通过调用__iter__方法就可得到一个生成器
# 迭代器特点
# 方便使用,但是迭代器中的数据只能取一次
# 节省内存空间

# 生成器:
# 本质上就是一个迭代器
# 生成器的表现形式
# 生成器函数
# 含有yield关键字的函数就是生成器函数
# 特点:
# 调用函数之后,返回一个生成器
# 每次调用next方法的时候就会取到一个值
# 知道取完最后一个值再执行next就会报错
# 取值方法:
# next
# for
# 数据类型的强制转换;此方法占内存
# 生成器表达式

# def generator():
#     for i in range(200):
#         yield "哇哈哈%s"%i

# g = generator()
# ret = list(g)     #数据类型强制转换,占内存
# print(ret)
# g = generator()     #调用函数得到一个生成器
# print(g)
# ret = g.__next__()
# print(ret)

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

# def generator():
#     print(123)
#     content = yield 1
#     print('====',content)
#     print(456)
#     arg = yield 2

# g1=generator()
# g2=generator()
# g1.__next__()
# g2.__next__()
# print('***',generator().__next__())
# print('***',generator().__next__())

# g = generator()
# ret = g.__next__()
# print('***',ret)
# ret = g.send('hello')
# print('***',ret)

# send:
# send获取下一个值的效果和next基本一致
# 只是在获取下一个值时,同时给上一个yield位置出传递一个参数
# 使用send的注意事项:
# 第一次使用生成器时,只能用next获取下一个值
# 最后一个yield无法接受外部值

# 计算移动平均值    avg = sum/count
# 10 20 30
# 10 15 20
# def average():
#     sum = 0
#     count = 0
#     avg = 0
#     while True:
#         num = yield avg
#         sum +=num
#         count+=1
#         avg = sum/count
# g = average()
# g.__next__()    #激活发生器
# g1 = g.send(10)   #执行到下一个yield才结束
# print(g1)
# g1=g.send(20)
# print(g1)

# 升级版,用一个装饰器去预激活一个生成器

# def actter(func):
#     def inner(*args, **kwargs):
#         ret = func(*args, **kwargs)
#         ret.__next__()  #在此激活生成器
#         return ret
#
#     return inner
#
# @actter
# def average():
#     sum = 0
#     count = 0
#     avg = 0
#     while True:
#         num = yield avg
#         sum += num
#         count += 1
#         avg = sum / count
#
# g = average()
# ret = g.send(10)
# print(ret)
# ret = g.send(90)
# print(ret)

# def l():
#     yield from range(20)
# print(list(l()))

# 列表解析
# egg_list=['鸡蛋%s'%i for i in range(10)]
#         #[存入方式 循环体 循环条件(可以有多个)]
# print(egg_list)
# egg_list = []
# for i in range(1000):
#     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)

# 老母鸡生成器,给蛋不如给老母鸡
# 老母鸡 = ('鸡蛋%s'%i for i in range(10))
# print(老母鸡)
# for 蛋 in 老母鸡:
#     print(蛋)

# g = (i*i for i in range(10))    #未执行时与函数定义一样,什么都不做
# print(g)
# for i in g:
#     print(i)

# 列表推导式
# 例一:30以内所有能被3整除的数
# print([i for i in range(31) if i%3==0])
# 例二:30以内所有能被3整除的数的平方
# print([i**2 for i in range(31) if i%3==0])
# 例三:找到嵌套列表中名字含有两个‘e’的所有名字
# names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
#          ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
# print([name for lis in names for name in lis if name.count('e')>=2])

# 字典推导式
# 例一:将一个字典的key和value对调
# mcase = {'a': 10, 'b': 34}
# mcase_frequency = {mcase[k]: k for k in mcase}
# print(mcase_frequency)
# 例二:合并大小写对应的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.keys()}
# print(mcase_frequency)

# 集合推导式
# 例:计算列表中每个值的平方,自带去重功能
# print({i*i for i in [1,-1,3]})
# 可迭代对象:
# 拥有__iter__方法
# 特点:惰性运算
#例如: range(), str, list, tuple, dict, set
# 迭代器Iterator:
# 拥有__iter__方法和__next__方法
# 例如: iter(range()), iter(str), iter(list), iter(tuple), iter(dict), iter(set), reversed(list_o), map(func,                                                                             list_o), filter(
# func, list_o), file_o
# 生成器Generator:
#   本质:迭代器,所以拥有__iter__方法和__next__方法
#   特点:惰性运算, 开发者自定义
# 使用生成器的优点:
# 1.
# 延迟计算,一次返回一个结果。也就是说,它不会一次生成所有的结果,这对于大数据量处理,将会非常有用。

猜你喜欢

转载自www.cnblogs.com/wujunjie-sir/p/9203213.html