迭代器

可迭代对象

     可以用for循环的都是可迭代对象,那么为什么有的对象可以用for循环,而有的确不行呢?

list
tuple
dict
set
range()
enumerate()
....

     这些对象都可以用for循环取得想要的值。

ls = dir(list)
tu = dir(tuple)
di = dir(dict)
se = dir(set)
ra = dir(range(10))
en = dir(enumerate([]))
#使用dir获得参数的属性,方法列表
s = set(ls) & set(tu) & set(di) & set(se) & set(ra) & set(en)
#取交集
print(s)

     在这些交集中有一个属性为__iter__。也正是因为这个属性,它们才可以被迭代,也就是用for循环。
     综上,当一个对象拥有__iter__方法时,它就是一个可迭代对象,也就可以用for循环。

迭代器

print(type([].__iter__()))
迭代器.png

     我们对列表使用一下__iter__()方法,查看它的类型发现它变成了iterator,也就是迭代器

print(dir([].__iter__()))
ls = [1,2,3]
iterator = ls.__iter__()
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())
迭代器.png

     在iterator的众多方法中有一个叫做__next__()的方法,使用它可以依次得到iterator中的值。
     同样它也有一个__iter__()方法,说明可以对iterator进行for循环

ls = [1,2,3]
iterator = ls.__iter__()
for i in iterator:
    print(i)

     当然我们也可以使用while

ls = [1,2,3]
iterator = ls.__iter__()
while True:
    print(iterator.__next__())
迭代器.png

     如果用while True将会一直取下一个元素,但如果没有下一个元素了怎么办,这时就会抛出一个StopIterator的异常,表示已经取到最后一个了,不能再往下继续了。

     现在来说说for的工作原理,如果给它的不是一个可迭代对象,它就直接报错,如果给它一个可迭代对象像list...它会先调用内置的__iter__()方法得到该对象的迭代器对象,然后调用迭代器对象的__next__()方法,一直依次向下取得迭代器对象中的每一个元素,直到迭代器没有下一个元素了。如果给它的直接是一个迭代器对象,那么就直接调用__next__()方法

Tips:

  • 如果一个对象有__iter__()方法,那么它就是一个可迭代对象
  • 如果一个对象既有__iter__()方法,又有__next__()方法,那么它就是一个迭代器对象
  • 由以上两点,迭代器一定是可迭代对象,但可迭代对象不一定是迭代器
  • 一个可迭代对象调用它的__iter__()方法,就可以返回一个迭代器对象
  • 调用迭代器的__next__()方法,可以一个一个地获取值。

isinstance

     如果我们要判断一个对象是不是一个可迭代对象或者是一个迭代器对象的时候,我们去查看dir,一个一个找它们是不是有__iter__()或是__next__(),实在太low,这时候我们使用isinstance()函数即可判断。

from collections import Iterable,Iterator
print(isinstance([],Iterable))
print(isinstance([],Iterator))
print(isinstance({1,2,3},Iterable))
迭代器.png

xrange和range

     现在讨论这个问题可能已经没有多大意义了,因为在Python3.x中xrange和range被统一为range

  • 在Python2.x中使用range()是生成一个序列
  • 在Python2.x中使用xrange()是生成一个迭代器,要一个值取一个,不需要一次性开辟一块很大的内存空间。因此在性能上xrange会比range更优。
    在Python3.x中xrange被range取代,也就是说只有range存在,并且生成的是一个迭代器。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容