一、可迭代
一组数据,可以使用for循环就是可迭代的。如python中的字符串、列表、字典、集合、元组。
二、迭代器
迭代器都是可迭代的,且迭代器可以使用next()方法。
from collections.abc import Iterable, Iteratorclass MyDatas:def __init__(self, n):# 传入参数,使用列表推导式生成一个列表self.data = [i for i in range(1, n + 1)]# 当前索引self.current_index = 0# 获取迭代器方法def __iter__(self):return self# 迭代器的next方法,依赖与__iter__方法def __next__(self):if self.current_index >= len(self.data):raise IndexError("取完了")else:result = self.data[self.current_index]self.current_index += 1return resultmd = MyDatas(5)
# print(md)
# 判断实例md是否是可迭代的,是否是迭代器
print(isinstance(md, Iterable), isinstance(md, Iterator))
# next(md)
while True:try: # 捕获异常print(next(md))except IndexError as e:# 返回异常对象eprint(e)break
三、生成器
生成器包含一组生成规则,生成器是装饰器,但生成器不能使用下标索引查找。当数据较多时,使用生成器更省内存。如元组推导式生成的就是一个生成器。
from collections.abc import Iterable, Iterator, Generator
# 生成器
def my_datas():# 使用yield声明生成元素yield 1yield 2yield 3yield 10return 100 # 不起平常使用的作用r = my_datas()
print(r)
print(type(r)) # 返回生成器类型
for i in my_datas():print(i)
while True:try:print(next(r)) # 捕获异常except StopIteration as e:print("取完了", e) # return的值赋值给ebreak
# 列表推导式
l0 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
print(l0.__sizeof__()) # 返回占用内存
# 元组推导式
t0 = (i for i in range(100))
print(t0.__sizeof__()) # 不能使用索引
# 生成器是可迭代的,是迭代器
print(isinstance(t0, Iterable), isinstance(t0, Iterator), isinstance(t0, Generator))
四、装饰器
装饰器本质是闭包,在不改变原函数结构的情况下为函数添加新功能。
# 装饰器
def cost_time(f):def calc():start = time.time()# 运行原有参数f()print(f"函数{f.__name__}开销:{time.time() - start}")# calc()return calcdatas = [random.randint(0, 10000) for i in range(10000)]
datas2 = datas.copy()# 使用@将原函数作为参数传递
@cost_time
def my_sort1():datas.sort(reverse=True)print(datas)@cost_time
def my_sort2():datas3 = sorted(datas2, reverse=True)print(datas3)my_sort1()
my_sort2()