简介
参考链接:Python3 列表解析和迭代器的内存占用过程分析_Leon的博客-CSDN博客
迭代器,在Python类中实现__iter__()就是一个可迭代对象,如果同时实现了next()就是一个迭代器。
正文
其实不是很能理解为什么要使用迭代器模式
很多网上的文章,都说可以节省内存。在和朋友激烈的讨论之后,得出以下结论。迭代器只有在无中生有的情况下才会节省空间。
举个例子,斐波那系数,每一个next都是上两个数相加得到的,如果我们需要第9个数,则需要next 9次,但是前8次的内存会被释放掉,为了证明列表生成器的内存更小,参考了下面的列子
import timeit
import os
import psutil
list = range(0,50000000)
# 计算占用内存
def show_memory_info(hint):
pid = os.getpid()
p = psutil.Process(pid)
info = p.memory_full_info()
memory = info.uss / 1024. / 1024
print('{} memory used: {} MB'.format(hint, memory))
# 时间
start1 = timeit.default_timer()
# 1.普通方法遍历元素,append 到新列表
list1 = []
show_memory_info('1')
for x in (list):
if x > 4:
list1.append(x)
show_memory_info('2')
end1 = timeit.default_timer()
print('Running time: {} Seconds'.format(end1 - start1))
# 2. 生成器生成元素到新列表,注意这里没有赋值到新列表
start2 = timeit.default_timer()
show_memory_info('3')
[x for x in (list) if x > 4]
show_memory_info('4')
end2 = timeit.default_timer()
print('Running time: {} Seconds'.format(end2 - start2))
测试结果如下:
1 memory used: 6.85546875 MB
2 memory used: 1942.71875 MB
Running time: 7.376570914 Seconds
3 memory used: 1942.71875 MB
4 memory used: 1382.83984375 MB
Running time: 6.350715519 Seconds
很明显发现列表生成及执行速度会比for循环快.(如果将列表换成元祖,执行速度更快,快了十倍不止。)原因百度查了一下说是,列表生成器底层使用C语言实现的,for循环则是先转换成pyc文件,再去Python虚拟机中转化成机器码执行。
下面再放一个斐波那系数的例子:
class Fibonacci():
def __init__(self, num) -> None:
self.a, self.b = 0,1
self.index = 0
self.num = num
def __iter__(self):
return self
def __next__(self):
tmp = self.a
if self.index < self.num:
self.a, self.b = self.b, self.a+self.b
self.index += 1
else:
raise StopIteration
return tmp
f = Fibonacci(10)
for i in f:
print(i)
总结
总结出迭代器的优点是,可以节省空间,可以将生成的规律写进next中,比for循环快。
生成器就是迭代器,迭代器就是迭代对象
迭代对象不一定是迭代器,迭代器不一定是生成器
迭代对象__iter__()返回的就是一个迭代器