python列表生成器语法_Python 列表生成式\生成器

Python 列表生成式+生成器

一、列表生成式

1.什么是列表生成器

一种可以便捷地生成列表的表达式,有时候可以替换list.append(变量)

2.需求. 如何将列表中的每个数据都加1

列表:data_list = [1,2,3,4,5]

方法一:思路.通过匿名函数+map进行处理

for i in map(lambda x: x + 1, data_list):

print(i)

输出结果:

2,3,4,5,6

方法二:通过for循环,使用enumerate通过下标取值 +1 进行处理

for index, line in enumerate(data_list):

data_list[index] += 1

print(data_list)

输出结果:

[2, 3, 4, 5, 6]

问题三:通过定义空列表,循环需要 +1 的列表进行i+1。append给新列表,然后赋值给需要+1的列表

date02 = []

for i in data_list:

date02.append(i + 1)

date01 = date02

print(date01)

print(date02)

输出结果:

[2, 3, 4, 5, 6]

[2, 3, 4, 5, 6]

问题四:

date02 = [i+1 for i in data_list]

print(date02)

输出结果:

[2, 3, 4, 5, 6]

拓展

使用三元运算将列表中大于几的数字进行固定加值或乘以几

将列表中大于3后的数字乘以10

date01 = [ i*10 if i > 3 else i for i in data_list]

print(date01)

输出结果:

[1, 2, 3, 40, 50]

二、生成器

2.1 定义

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

如果. 列表元素可以按照某种算法推算出来.那么我们是否可以在循环的过程中不断推算出后续的元素?这样就不必创建完整的list,从而节省大量的空间.在python中.这种一边循环一边计算的机制.称为生成器(generator)[也成惰性运算.(用到我就算.没用到我就不算)]

2.2 生成器和列表的区别

列表:

优点:取值快,无须进行运算  缺点:占用空间【浪费空间】

生成器:

优点:节省空间        缺点:取值慢需要进行运算【不支持下标取值,只能从前往后取,无法进行跳着取】

2.3 作用

生成一个推到算法,边运算边生成

2.4 定义语法

创建generator的方法很多.最简单的如下:把一个列表生成式的[]改成(). 就创建了一个generator

列表生成式

L = [x * x for x in range(5)]

print(L)

0  1 4  9 16

生成器( at 0x00000000007E7A40>是生成器内存对象)

L = (x * x for x in range(5))

print(L)

at 0x00000000007E7A40>

2.5 取值

生成器取值可通过for循环进行取值. 也可使用L.__next__()或next(L)来进行取值.

PS:访问顺序只能从头开始取.不能跳着取.【取完值后.内存丢弃generator内存地址.不会进行保存.】

如果使用L.__next__()或next(L)取完值后会报StopIteration.抛异常. So.取值我们一般使用for循环进行取.因为generator也是可迭代对象.

使用for循环取值.如下:

L = (x * x for x in range(5))

for i in L:

print(i)

输出:0 1 4 9 16

使用__next__()或next()取值.如下:【ps:在此提醒.如果取值后再取的话会报StopIteration错误异常】

L = (x * x for x in range(5))

print(L.__next__())

print(L.__next__())

print(L.__next__())

print(next(L))

print(next(L))

输出:0 1 4 9 16

2.6 斐波拉契:

generator非常强大.如果推算的算法比较比较复杂.用类似列表生成式的for循环无法实现的时候.还可以用函数来实现.

著名的斐波拉契数列(Fibonacci).除第一个和第二个数外任意一个数都可由前两个数相加.斐波拉契用列表生成式写不出来.用函数把它打印出来却很容易

如:1 1 2 3 5 8 13 21 55 ...【解释:此处的意思就是. 2等于1 + 1 . 3等于1 + 2 . 5等于2 + 3. 8等于3 + 5. 以此类推】如下代码:

def Fib(num):

"""

:param num:此处num代表求几次

:return:  #1  1  2  3  5  8  13  21

"""

count = 0

a, b = 0, 1 # 等于a = 0 ,b = 1

while count < num:

tmp = a

a = b

b = a + tmp

print(a)

count += 1

print("done.....")

Fib(15)

输出:1 1 2 3 5 8 13 21 done....

以上实例可以看出定义了斐波拉契数列的推算规则.可以从第一个元素推算出后续任意元素.这种逻辑很像generator.

上边函数斐波拉契函数和generator仅一步之遥.如何将Fib函数变成generator ?只需把print(a)改为yield b就可以.如下代码:

#可粘贴复制代码运行查看代码

def Fib(num):

"""

:param num:此处num代表求几次

:return:

"""

count = 0

a , b = 0 , 1 # 等于a = 0 ,b = 1

while count < num:

tmp = a

a = b

b = a + tmp

#  """此处还可这样写:a,b = b,a+b 和上边的效果一样."""

# print(a)  # 此处print(a)是打印第一次循环到这的值.注释后看起来更可观

count += 1

yield a # 返回a. 同时挂起当前这个函数.a返回给了通过__next__()或next()调用当前函数的人

print("done.....")

F = Fib(8) # 生成一个生成器对象. 就是代表推到公式准备好了的意思

print(F.__next__()) # 推算取值.  此处打印的值是yield a的结果.

print(F.__next__()) # 推算取值.  此处打印的值是yield a的结果.

print(next(F)) # 推算取值 print(F) # 查看是否什么类型 输出

执行结果:

1 1 2

函数中加yield是生成器. 如果不加yield则是函数.

yield a 作用:yield 返回a.相当于挂起这个函数.不结束.a返回给了通过__next__()或next()调用当前函数的人.后续调起用__next__()或next()

通过yield实现了函数的中断. 并保存了函数的中间执行状态

return a 作用:return 返回函数运行结果并结束函数

总结:

生成器定义方法:

1.通过L = (x * x for x in range(5))【列表生成式的方法使用()小括号进行定义】

2.复杂的推到算法使用yield进行实现【看以上实例】

2.7 使用yield实现单线程并发【实际是单线程】

import time

def consumer(name):

print("%s 来来来来上狗不理包子了!" % name)

while True:

baozi = yield

print("狗不理[%s]来了. 被[%s].全给吃了! " % (baozi, name))

def producer(name):

c1 = consumer("Harry")

c2 = consumer("ZhanSan")

c1.__next__()

c2.__next__()

print("小二赶紧做包子耶. 都等着呢!")

for i in range(10):

time.sleep(1)

print("好嘞.狗不理包子已做好2个了")

"""

send作用:

相当与__next__(). 并且可以传递数据给yield并且唤醒

而__next__()不能传递特定的值. 只能传递None进去

"""

c1.send(i)

c2.send(i)

# 此处的YuHongLin表示是谁调用的词函数.

producer("Ennnn.....")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值