迭代器
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一 个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
生成器
而生成器本身就是一个迭代器
返回可迭代项集的函数称为生成器。
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
内置函数
map()
会根据提供的函数对指定序列做映射
map(function, iterable, ...)
list(map(lambda x: x ** 2, [1, 2, 3, 4, 5])) # 使用 lambda 匿名函数
>>> [1, 4, 9, 16, 25]
zip()
函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b) # 返回一个对象
>>> zipped
<zip object at 0x103abc288>
>>> list(zipped) # list() 转换为列表
[(1, 4), (2, 5), (3, 6)]
>>> list(zip(a,c)) # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
zip() 和 * 操作符一起操作可以用来 unzip 一个列表,看下面的代码:
import numpy as np a=[1,2,3] b=[4,5,6] c=[7,8,9] zz=zip(a,b,c) print(zz) x,y,z=zip(*zz) print(x) print(y) print(z) 输出: [(1, 4, 7), (2, 5, 8), (3, 6, 9)] (1, 2, 3) (4, 5, 6) (7, 8, 9)
await/async
async def async_fun():
return 1
if __name__ == '__main__':
print(async_fun()) # <coroutine object fun at 0x0000000002156E08>
print(async_fun().send(None)) # StopIteration: 1
try:
async_fun().send(None)
except StopIteration as e:
print(e.value)
异步函数的调用返回的是一个协程对象,若改对象通过send()进行调用,会报一个StopIteration错,若要取值,就需要捕获该异常,e.value的形式进行获取。
在协程函数中,可以通过await语法来挂起自身的协程,并等待另一个协程完成直到返回结果:
async def async_function():
return 1
async def await_coroutine():
result = await async_function()
print(result)
run(await_coroutine())
# 1
python的GIL
GIL 是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大
classmethod 修饰符
classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。
class A:
a=1
def __init__(self):
pass
def do(self):
print(self.a)
@classmethod
def hhh(cls):
print(cls.a)
cls.do() ##就会有问题 cls().do()才对,cls在这里相当于A
if __name__ == '__main__':
A.hhh() #不需要实例化