8.推导式、迭代器、生成器

推导式、迭代器、生成器

一、推导式

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 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值