写的很墨迹,将就看。
首先 理解 for 循环
for i in [1,2,3,4]
print i
这个是正常
如果 for 循环一个 1234
会报错,因为 int 不是一个 iterable 类型
iterable : 字典里的意思是 可迭代的, 可重复的
可迭代的对象: 字符串str 列表 list 元组 tuple 字典 dict 集合set
#证明是否可迭代
from collections import Iterable
l = [12,3,4]
t = (1,2,3,4)
d = {1:2,3:4}
s = {1,2,3,4}
print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(s,Iterable))
# 清一色的 True
结合 for 循环取值的现象,再从字面上理解一下
迭代其实就是 : 可以将某个数据 一个接着一个取出来
那么可迭代协议这么理解呢?
首先,能被 for 循环的就是‘可迭代的’可以被迭代满足的要求就叫做迭代器协议。
可迭代协议的定义: 内部实现了__iter__方法。
综上总结!!! 可以被 for 循环的都是可迭代的,要想可迭代,内部必须有一个__iter__方法。
那么这个__iter__做了些什么事?
print([2,3,4].__iter__())
输出结果:<list_iterator object at 0x1005d94a8>
Iterable 可迭代
iterator 迭代器
迭代器是个什么鬼东西, 一会一个可迭代,一会一个迭代器,我英语一直都不好, 我也没打算再补。。。
为了python 我忍了
好 那么,我们来看一看这个带 iter 的列表和普通列表在功能实现上面有什么不一样 好不好
''''
l([1,2].__iter__())是列表迭代器中实现的所有方法,l[1,2]是列表中实现的所有方法,
都是以列表的形式返回给我们,为了看的更清楚,我们分别把他们转换成集合。 然后取差集
'''
#
# print(dir([1,2].__iter__()))
# print(dir([1,2]))
print(set(dir([1,2].__iter__())) - set(dir(dir([1,2]))))
#注意盯着看你的括号是否给到位
输出结果:
/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 "/Users/macbookpro/PycharmProjects/迭代器生成器/blog 代码.py"
{'__length_hint__', '__next__', '__setstate__'}
Process finished with exit code 0
重点就看 最后多出来的那三个方法
{'__length_hint__', '__next__', '__setstate__'}
那么我们继续来看这三个方法,分别都是干啥的,什么来路!
iter_l = [1,2,3,4,5,6].__iter__()
#获取迭代器中元素的长度 print(iter_l.__length_hint__())
#根据索引值指定从哪里开始迭代 print('*',iter_l.__setstate__(4))
!!!!!!#一个一个的取值 print('**',iter_l.__next__()) print('***',iter_l.__next__())
好的,这三个办法我们都一个个试过了。
来, 跟着我回归一下初心 扪心问问自己,今天我们学的是啥。
对,最上面写的有,但是我怕我忘,在这再回忆一下。
能用 for 循环的的都是可迭代的,可迭代的内部都使用了__iter__方法
__iter__是根据可迭代协议定出来的,没有为什么 你就这样记就行
然后响指!各位宝贝, 上述三个方法中,能一个一个取值,感觉和 for 循环一样样的是谁?
对!没错!是他!我们的朋友,小哪吒= __next__
再 for 循环中,就是在内部调用了__next__方法,才能一个一个取值
'''
我是很纯很纯并且很蠢and 年龄还大的小白一个,啥也不会,脑子也笨,刚看过的句子 ,到句号 我就忘记句号前面的东西了。
代码没思路 也理解不了, 我要是真的会,我干嘛要一遍一遍的翻博客,早进行下面的东西了,
但是这个东西,你学会了 别人也拿不走,以后说不定 你多会一句, 你就能比别人多装一个很完美
逼格很高的比了
目前我的办法是, 只要有时间, 理解代码理解思路
刚开始看到这么一堆我20多年没见过没接触的11002200312030还有这个那个 的时候
我是懵逼 并且很不把它当做一回事的,
可是 真的 被这个破 python 教育的不要不要的, 没有什么不劳而获,就算有那个人也不是你
深深深深深深*******n 的挫败感 越是让我不好受,我越要征服你。
各位一起加油!!!
'''
来,接着上面,我们码起来, 你看再多,不如自己照着码一遍有用,码一遍你没收获,那就再码继续码
#用迭代器的 next 方法来写一个不依赖 for 的遍历
l = [1,2,3,4]
'''
__iter__是上面说过的,
想要可迭代内部必须有__iter__方法
这里就是先调用这个方法,让这个列表可迭代
然后下面就是用__next__取值
'''
l_iter = l.__iter__()
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
打印结果:
StopIteration
1
2
3
4
报错了,但是这个报错我们不尴尬,因为我们把迭代器里的元素取完了,然后你还要取它就给
你抛出一个异常StopIterration,就是在告诉我们,列表中已经没有有效的元素了。
如何处理呢?
comeon
l = [1,2,3,4]
#先把它转化为可迭代的用 iter
l_iter = l.__iter__()
while 1 :
try:
#取它值 用 next
item = l_iter.__next__()
print(item)
except StopIteration:
break
好, 那么everybody ,我们是如何用 while 循环来实现 for 循环的功能呢,
来看 我们是从谁哪里拿的一个又一个的值啊, 是妈妈?!
l_iter 就是一个迭代器
so 总结一下: 迭代器遵循迭代器协议:必须拥有__iter__和__next__方法。
来吧, 看一下 range()是个什么鬼。我们目前可以确定的是, 它肯定是一个可迭代对象,来查一波
看看他是不是一个迭代器
print('__next__'in dir(range(7)))
print('__iter__'in dir(range(7)))
from collections import Iterator
print(isinstance(range(100),Iterator))
打印结果: False True False
so想要可迭代 内部必须有__iter__方法和__next__方法 so range()不是一个迭代器
是,很多东西我们也可以通过下标来取值, 比如序列类型字符串,列表,元组
但是,那些没有下标的呢,它们不要面子的吗? 你觉得字典,集合这些非序列类型不够漂亮吗?
so for 循环就是基于迭代器协议提供了一个统一的可以遍历所有对象的方法,就是我们上面说的
调用对象的__iter__方法将其转换成一个迭代器,然后使用迭代器协议取实现循环访问,这样
所有的对象就都可以通过 for 循环来遍历了。
下一篇是生成器。