迭代器python菜鸟_菜鸟世界 -python进阶---迭代器

1、概念介绍

1.1 什么是迭代器

最早是在使用C++的STL时接触到迭代器的概念,后来接触数据库时也遇到了迭代器的概念,这就不得不感叹英语在某些编程概念上的表达要优于中文,迭代器乍一听起来好困惑,但用英语“one by one”做最直观的解释就清晰许多。

更专业的描述,一个对象,如果它实现了next方法,那么它就是一个迭代器

1.2 什么是可迭代对象

如果一个对象实现了__iter__方法,那么它就是一个可迭代对象

2、 掀开面纱

接下来,我们一步步掀开迭代器的神秘面纱

2.1 内置函数  iter

内置函数 iter会调用对象的__iter__方法,返回一个迭代器,看示例

#coding=utf-8

lst = [1,2,3,]

iter_lst = iter(lst)

print type(iter_lst)

iter_lst的类型是   ,注意,这是一个迭代器

对这一小段代码,我们要明确一点,lst 是列表,列表是可迭代对象,因为列表实现了__iter__方法,为什么我说列表实现了__iter__方法呢,因为内置函数iter作用于lst时返回了一个迭代器,再看一遍内置函数iter的解释,你就能明白这句话

2.2 迭代器的next方法

上面的示例代码里,iter_lst是一个迭代器,那么如何使用它呢,看下面的示例代码

#coding=utf-8

lst = [1,2,3,]

iter_lst = iter(lst)

print type(iter_lst)

print iter_lst.next()

print iter_lst.next()

print iter_lst.next()

print iter_lst.next()

四个print语句,前三个都能正常执行,打印出1 ,2 ,3 。但是最后一个回引发 StopIteration异常,毕竟迭代器里只有三个元素可以迭代,因此最后一次迭代时会引发异常。

next这个方法名定义的非常好,迭代,就是一个接一个,one by one ,这正是迭代的本质。

2.3 for 循环

每当我们用for 循环遍历序列对象时,其实本质上都是在使用迭代器,看下面的示例代码

#coding=utf-8

lst = [1,2,3]

iter_lst = iter(lst)

for item in lst:

print item

for item in iter_lst:

print item

两次for 循环都能正确执行,都会打印出 1 ,2 ,3 ,那么他们的区别在哪里呢?

第一个for循环,in 后面是lst,其实呢,本质上是用内置函数iter返回了lst的迭代器,因此和第二个for循环是等价的,第一个for循环包含了 iter_lst = iter(lst)  这个过程

2.4 迭代器的特性

(1)迭代器是单向的

迭代器迭代的过程是单向的,就上面的示例而言,只能从1迭代到3

(2) 不能重头再来

所有元素都迭代结束之后,next函数会抛出一个StopIteration 异常,这个迭代器已经坏掉了,不能再使用了

#coding=utf-8

lst = [1,2,3]

iter_lst = iter(lst)

print u'第1次'

for item in lst:

print item

print u'第2次'

for item in lst:

print item

print u'第3次'

for item in iter_lst:

print item

print u'第4次'

for item in iter_lst:

print item

执行上面这段代码,前3个for循环能正确执行,但是第4个for循环却不能打印任何东西

前两个for循环一模一样,后两个for循环一模一样,不同的是,后两个for循环在for ... in ...句式中,in 后面是iter_lst,而iter_lst是迭代器,而迭代器是不能重头再来的,在for循环里,永远在调用迭代器的next方法,可是在第3次for循环中,迭代器已经将所有的元素都迭代完了,已经抛出了StopIteration 异常,之所以没有报错,是因为for循环已经处理了这个异常,第4次for循环,再次迭代,仍然引发异常,for循环捕捉这个异常,不会报错,也不会进入for循环。

前两个for循环都能正确执行,是因为,每一次for循环,都返回一个新的迭代器,这样,每次都从头开始,而后两个for循环,始终都用iter_lst,由于不能重头再来,所以最后一次使用时就没效果了

(3) 迭代过程中对元素的修改是无效的

#coding=utf-8

lst = [1,2,3]

iter_lst = iter(lst)

for item in iter_lst:

item = 0

print lst

迭代过程中,将item赋值为0,最终lst里元素的值会改变么?答案是不会

费了这么多力气,搞出一个叫迭代器东东,绝不是闲来无事,编程世界的这些技术,或者说概念,那是无数聪明的工程师,科学家智慧的结晶,看似平淡无奇,其实都有着我们常人想不到的深意。看下面的代码

#coding=utf-8

lst = [1,2,3]

iter_lst = iter(lst)

for i in range(3):

print lst[i]

for item in iter_lst:

print item

第一个for循环里,是直接通过元素的位置来访问元素,第二个for循环,是使用迭代器,那么问题来了,哪个更安全呢?当然是第二个,通过元素位置访问lst中元素时,是可以直接修改lst里的元素的,而且修改是有效的,但是在通过迭代器遍历lst时,不论怎样修改,都是无效的

(4)迭代非序列类型

如果你对迭代器嗤之以鼻,认为按照元素位置遍历访问也没问题,那么现在给你出一个难题,请遍历集合中的元素

集合中的元素是无法通过元素位置来遍历访问的,因为集合中的元素没有位置,这时,使用迭代器就可以了

#coding=utf-8

lst = [1,2,3]

lst_set = set(lst)

iter_lst = iter(lst_set)

print type(iter_lst)

for item in iter_lst:

print item

不光是集合,字典也可以

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值