python迭代器
好久不用python,迭代器的一些知识遗忘了,这篇帖子说一些迭代器;迭代是Python最强大的功能之一,是访问集合元素的一种方式。 迭代器是一个可以记住遍历的位置的对象。 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。 迭代器只能往前不会后退
迭代器有两个基本的魔法方法: iter ()和 next()。
- 引入
从最简单的讲起,其实迭代器我们一直在用,只是我们不知道罢了
A = [1,2,3,4]
for i in A:
print(i)
这里的for循环的工程画为图表解释其实为: 在循环遍历自定义容器对象时,会使用python内置函数iter()将可迭代对象转换为迭代器,之后再循环对这个迭代器使用next()调用迭代器对象的__next__()。iter()只会被调用一次,而__next__()会被调用 n 次。
- 迭代器的优点
从迭代器和可迭代对象角度来看问题,可迭代对象不能使用next来进行内容的提取和遍历,可迭代对象内部的属性都只有iter函数,但是没有next函数;迭代器中同时含有next函数和iter函数;
可迭代对象的优点: 可以直观查看里面的对象,如直接查看列表的内容 可迭代对象缺点:
- 全部内容要加载至内存中,故占用内存;
- 可迭代对象不能迭代取值(除了索引,key外)
迭代器与列表的区别在于,构建迭代器的时候,不像列表把所有元素一次性加载到内存,而是以一种延迟计算(lazy evaluation)方式返回元素,这正是它的优点。比如列表中含有一千万个整数,需要占超过100M的内存,而迭代器只需要几十个字节的空间。因为它并没有把所有元素装载到内存中,而是等到调用next()方法的时候才返回该元素(按需调用 call by need 的方式,本质上 for 循环就是不断地调用迭代器的next()方法)
迭代器的优点:
- 提供了一种通用不依赖索引的迭代取值方式;
- 节省内存,迭代器在内存中相当于只占一个数据的空间:因为每次取值都上一条数据会在内存释放,加载当前的此条数据
迭代器缺点 1) 因为有next方法,即只能往后取值,不能往前,取值不如按照索引的方式灵活,不能取指定的某一个值; 2) 无法预测迭代器的长度。
- 自定义一个迭代器
class Fib(object):
"""
斐波那契数列的迭代器
"""
def __init__(self, max=0):
self.prev = 0
self.curr = 1
self.max = max
def __iter__(self):
return self
def __next__(self):
if self.max > 0:
self.max -= 1
value = self.curr
self.curr += self.prev
self.prev = value
return value
else:
raise StopIteration
def next(self):
return self.__next__()
if __name__ == '__main__':
fib = Fib(10)
for n in fib:
print(n)
- python一切皆对象的完美解释
Python 中的一切都可以赋值给变量或者作为参数传递给函数。 每个对象都有标识(ID),类型和值组成。对象一旦建立,它的 ID 就不会改变;我们可以把它理解为该对象在内存中的地址。is 操作符比较两个对象的 ID;id() 函数返回一个表示对象 ID 的整数。对象的类型决定对象能够支持的操作(例如,它是否具有长度?),还定义该类型的对象可能有的值/取值范围。type() 函数返回对象的类型(它本身也是一个对象)。与 ID 一样,对象的类型也是不可以修改的
python对象的三个重要的特性: 身份Id,类型,值 每个对象在创建的时候就有了这三个属性,并且当多个变量都引用了相同的对象,成为共享引用;对象包含一个引用的计数器,计数器记录了当前指向该对象引用的数目,一旦对象的计数器为0,即不存在该对象的引用的时候,这个对象的内存空间就会被释放,python中在编写代码的时候不需要考虑释放内存空间 可以使用sys模块中的getrefercount来查询一个对象计数器的值
|