python列表推导式生成随机数_python 【迭代器 生成器 列表推导式】

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-29 23:10   370   0

python 【迭代器 生成器 列表推导式】

一、迭代器

1、迭代器

如何从列表、字典中取值的

index索引 ,key

for循环

凡是可以使用for循环取值的都是可迭代的

可迭代协议 :内部含有__iter__方法的都是可迭代的

迭代器协议 :内部含有__iter__方法和__next__方法的都是迭代器

print(dir([1,2,3]))

lst_iter = [1,2,3].__iter__()

print(lst_iter.__next__())

print(lst_iter.__next__())

print(lst_iter.__next__())

for i in [1,2,3]: # [1,2,3].__iter__()

print(i)

l = [1,2,3]

lst_iter = iter(l) # l.__iter__()

while True:

try:

print(next(lst_iter)) # lst_iter.__next__()

except StopIteration:

break

2、什么是可迭代的

什么是迭代器===》迭代器 = iter(可迭代的),自带一个__next__方法

可迭代 最大的优势 节省内存

from collections import Iterable,Iterator

print(range(100000000))

print(isinstance(range(100000000),Iterable)) #判断当前是否是一个可迭代的

print(isinstance(range(100000000),Iterator)) #是不是一个迭代器

py2 range #不管range多少 会生成一个列表 这个列表将用来存储所有的值

py3 range #不管range多少 都不会实际的生成任何一个值

3、迭代器优势

a、节省内存

b、取一个值就能进行接下来的计算 ,而不需要等到所有的值都计算出来才开始接下来的运算 —— 快

4、迭代器的特性:惰性运算

二、生成器 Generator

自己写的迭代器 就是一个生成器

两种自己写生成器(迭代器)的机制:生成器函数 生成器表达式

1、生成器函数 ---凡是带有yield的函数就是一个生成器函数

def func():

print(‘****‘)

yield 1

print(‘^^^^‘)

yield 2 # 记录当前所在的位置,等待下一次next来触发函数的状态

g = func()

print(‘--‘,next(g))

print(‘--‘,next(g))

# 生成器函数的调用不会触发代码的执行,而是会返回一个生成器(迭代器)

# 想要生成器函数执行,需要用next

def cloth_g(num):

for i in range(num):

yield ‘cloth%s‘%i

g = cloth_g(1000)

print(next(g))

print(next(g))

print(next(g))

2、使用生成器监听文件输入的例子

import time

def listen_file():

with open(‘userinfo‘) as f:

while True:

line = f.readline() #readline 不会自动停止

if line.strip():

yield line.strip()

time.sleep(0.1)

g = listen_file()

for line in g:

print(line)

3、send关键字

def func():

print(11111)

ret1 = yield 1

print(22222,‘ret1 :‘)

ret2 = yield 2

print(33333,‘ret2 :‘,ret2)

yield 3

g = func()

ret = next(g)

print(ret)

print(g.send(‘alex‘)) # 在执行next的过程中 传递一个参数 给生成器函数的内部

print(g.send(‘金老板‘))

# 想生成器中传递值 有一个激活的过程 第一次必须要用next触发这个生成器

生成实例:计算移动平均值

#月度 的 天平均收入

def average():

sum_money = 0

day = 0

avg = 0

while True:

money = yield avg

sum_money += money

day += 1

avg = sum_money/day

g = average()

next(g)

print(g.send(200))

print(g.send(300))

print(g.send(600))

5、预激生成器

def init(func):

def inner(*args,**kwargs):

ret = func(*args,**kwargs)

next(ret) # 预激活

return ret

return inner

@init

def average():

sum_money = 0

day = 0

avg = 0

while True:

money = yield avg

sum_money += money

day += 1

avg = sum_money/day

g = average()

print(g.send(200))

print(g.send(300))

print(g.send(600))

6、yield from

def generator_func():

yield from range(5)

yield from ‘hello‘

for i in range(5):

yield i

for j in ‘hello‘:

yield j

g = generator_func()

for i in generator_func():

print(i)

g1 = generator_func()

g2 = generator_func()

next(generator_func())

next(generator_func())

6、如何从生成器中取值

第一种 :next 随时都可以停止 最后一次会报错

print(next(g))

print(next(g))

第二种 :for循环 从头到尾遍历一次 不遇到break、return不会停止

for i in g:

print(i)

第三种 :list tuple 数据类型的强转 会把所有的数据都加载到内存里 非常的浪费内存

print(g)

print(list(g))

7、总结:

生成器函数 是我们python程序员实现迭代器的一种手段

主要特征是 在函数中 含有yield

调用一个生成器函数 不会执行这个函数中的带码 只是会获得一个生成器(迭代器)

只有从生成器中取值的时候,才会执行函数内部的带码,且每获取一个数据才执行得到这个数据的代码

获取数据的方式包括: next send 循环 数据类型的强制转化

yield返回值的简便方法,如果本身就是循环一个可迭代的,且要把可迭代数据中的每一个元素都返回 可以用yield from

使用send的时候,在生成器创造出来之后需要进行预激,这一步可以使用装饰器完成

生成器的特点 : 节省内存 惰性运算

生成器用来解决 内存问题 和程序功能之间的解耦

8、列表推导式

new_lst = []

for i in range(10):

new_lst.append(i**2)

print(new_lst)

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

l = [1,2,3,-5,6,20,-7]

print([i%2 for i in range(10)])

l = [1,2,3,-5,6,20,-7]

print([num for num in l if num%2 == 1])

#30以内所有能被3整除的数

print([i for i in range(30) if i%3 ==0])

#30以内所有能被3整除的数的平方

print([i**2 for i in range(30) if i%3 ==0])

#找到嵌套列表中名字含有两个‘e’的所有名字

names = [[‘Tom‘, ‘Billy‘, ‘Jefferson‘, ‘Andrew‘, ‘Wesley‘, ‘Steven‘, ‘Joe‘],

[‘Alice‘, ‘Jill‘, ‘Ana‘, ‘Wendy‘, ‘Jennifer‘, ‘Sherry‘, ‘Eva‘]]

print([name for name_lst in names for name in name_lst if name.count(‘e‘) == 2])

9、生成器表达式

l = [i for i in range(30) if i%3 ==0] # 列表推倒式 排序的时候

g = (i for i in range(30) if i%3 ==0) # 生成器表达式 庞大数据量的时候 使用生成器表达式

print(l)

print(g)

for i in g:print(i)

10、面试题

def demo():

for i in range(4):

yield i

g=demo()

g1=(i for i in g)

g2=(i for i in g1)

print(list(g1))

print(list(g2))

def add(n,i):

return n+i

def test():

for i in range(4):

yield i

g=test()

for n in [1,3,10]:

g=(add(n,i) for i in g)

print(list(g))

#一个生成器 只能取一次

#生成器在不找它要值的时候始终不执行

#当他执行的时候,要以执行时候的所有变量值为准

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP