推导式、迭代器、生成器
一、推导式
1. 列表推导式
列表推导式是一种快速生成列表的方式,结构是用方括号括起来包含一个任意的表达式,然后是一个for语句,然后是 0 个或多个 for 或者 if 语句,各语句之间是嵌套关系
例1:
lis = [x * x for x in range(1, 10)]
# 等同于
lis = []
for i in range(1, 10):
lis.append(i*i)
print(lis)
**********************************************************************
[1, 4, 9, 16, 25, 36, 49, 64, 81]
例2:
lis = [x * y for x in range(1, 5) if x > 2 for y in range(1, 4) if y < 3]
# 等同于
lis = []
for x in range(1, 5):
if x > 2:
for y in range(1, 4):
if y < 3:
lis.append(x * y)
print(lis)
**********************************************************************
[3, 6, 4, 8]
例3:
dic = {"k1": "v1", "k2": "v2"}
a = [k + ":" + v for k, v in dic.items()]
print(a)
**********************************************************************
['k1:v1', 'k2:v2']
2.字典推导式
使用大括号{}制造字典推导式
dic = {x: x**2 for x in (2, 4, 6)}
print(dic)
**********************************************************************
{2: 4, 4: 16, 6: 36}
3.集合推导式
使用大括号{}制造集合推导式
se = {x for x in 'abcdefacf' if x not in 'abc'}
print(se)
**********************************************************************
{'d', 'f', 'e'}
4.综合匿名函数
result = [lambda x: x + i for i in range(10)]
print(result[0](10)) # 19
# 等同于
def result(i):
for i in range(10):
def num(x):
res = x + i
return res
return num
print(result(0)(10))
**********************************************************************
19
result = [lambda x, j=i: x + j for i in range(10)]
print(result[0](10)) # 10
# 等同于
def result(i):
jj = i
for i in range(10):
def num(x, j=jj):
res = x + j
return res
return num
print(result(0)(10))
**********************************************************************
10
二、迭代器(Iterator)
1.概念
-
迭代是指通过for循环遍历对象的每一个元素的过程(依次从数据结构中拿出东西的过程)
-
字符串、列表、元组、集合、字典、生成器,都可以放到 for 循环里被加以处理,所以被称为可迭代对象
-
只有生成器可以被直接拿来当做迭代器,其他数据类型,需要用
iter()
函数处理之后才能当成迭代器即
迭代器=iter(可迭代对象)
-
迭代器便于循环比较大的数据结构,节省内存,访问者不需要关心内部结构,只需要通过next不断去取下一个内容,内容只能从头到尾依次访问,不能回退
2.区分迭代器和可迭代对象
- 凡是可作用于for循环的对象都是可迭代对象
- 凡是可作用于next()函数的对象都是迭代器
# 可迭代对象
lis = [1, 2, 3]
print(dir(lis)) # '__iter__'
"""
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
"""
# 迭代器
a = iter(lis)
print(dir(a)) # '__iter__','__next__'
"""
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']
"""
3.for实现迭代的原理
Python的for循环本质上就是通过不断调用next()函数实现的
lis = [1, 2, 3]
a = iter(lis)
print(next(a)) # 1
print(next(a)) # 2
print(next(a)) # 3
print(next(a)) # 抛出异常:StopIteration
lis = [1, 2, 3]
a = iter(lis)
try:
while True:
var = next(a)
print(var)
except StopIteration:
pass
三、生成器(generator)
1.概念
- 生成器是一种特殊的迭代器,是优雅的自定义迭代器的方式,是一边循环一边计算出元素的机制
- 与普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作
- 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行
- 调用一个生成器函数,返回的是一个迭代器对象
- 生成器与yield:类似于函数的逻辑,支持显式的暂停与恢复,隐式的支持迭代协议
2.生成器推导式
通过圆括号可以编写生成器推导式
g = (x * x for x in range(1, 4))
print(g)
for i in g:
print(i)
**********************************************************************
<generator object <genexpr> at 0x000001FE426C2CF0>
1
4
9
3.yield
关键字
语法:yield 一个对象
,调用时暂停这个函数,返回这个对象,等待下次next()重新激活
解释:在 Python中,使用yield返回的函数会变成一个生成器,在调用生成器的过程中,每次遇到yield时函数会暂停并保存当前所有的运行信息,返回yield的值,并在下一次执行next()方法时从当前位置继续运行
# 斐波那契函数
def fibonacci(n):
a, b, counter = 0, 1, 0
while True:
if counter > n:
return # return是为了跳出函数,可换成break
yield a # yield让该函数变成一个生成器
a, b = b, a + b # 赋值语句,先计算等值右边,在赋值给左边
counter += 1
fib = fibonacci(10) # fib是一个生成器
print(type(fib))
for i in fib:
print(i, end=" ")
**********************************************************************
<class 'generator'>
0 1 1 2 3 5 8 13 21 34 55