Python 中 Iterator和Iterable的区别
转自: https://www.cnblogs.com/meditator/p/7943582.html
(转载:http://blog.csdn.net/passionkk/article/details/49929887)
Python中 list,truple,str,dict这些都可以被迭代,但他们并不是迭代器。为什么?
因为和迭代器相比有一个很大的不同,list/truple/map/dict这些数据的大小是确定的,也就是说有多少事可知的。但迭代器不是,迭代器不知道要执行多少次,所以可以理解为不知道有多少个元素,每调用一次next(),就会往下走一步,是惰性的。
判断是不是可以迭代,用Iterable
from collections import Iterable
isinstance({}, Iterable) --> True
isinstance((), Iterable) --> True
isinstance(100, Iterable) --> False
判断是不是迭代器,用Iterator
from collections import Iterator
isinstance({}, Iterator) --> False
isinstance((), Iterator) --> False
isinstance( (x for x in range(10)), Iterator) --> True
所以,
凡是可以for循环的,都是Iterable
凡是可以next()的,都是Iterator
集合数据类型如list,truple,dict,str,都是Itrable不是Iterator,但可以通过iter()函数获得一个Iterator对象
Python中的for循环就是通过next实现的
for x in [1,2,3,4,5]:
pass
等价于
#先获取iterator对象
it = iter([1,2,3,4,5])
while True:
try:
#获取下一个值
x = next(it);
except StopIteration:
# 遇到StopIteration就退出循环
break
可迭代对象
#_*_ encoding: utf-8 _*_ @author: ty hery 2018/10/10
class Row(object):
def __init__(self,data):
self.data = data
def __iter__(self):
# return iter([11,22,33,44])
yield '<div>'
yield '全部'
for item in self.data:
yield f"<a href='xxx'>{item}</a>"
yield "</div>"
data_list =[
Row(['1升以下','1.1-1.6']),
# Row(['汽油','柴油','混合动力','电动']),
]
r = Row(['汽油','柴油','混合动力','电动'])
print(r,r.__iter__())
for x in r:
print(x)
输出:
<__main__.Row object at 0x0000000009FF4F98> <generator object Row.__iter__ at 0x0000000009FDD990>
<div>
全部
<a href='xxx'>汽油</a>
<a href='xxx'>柴油</a>
<a href='xxx'>混合动力</a>
<a href='xxx'>电动</a>
</div>
可迭代对象和list的区别:
li = [1,2,3,4,5]
for item in li:
print(item)
class Foo(object):
def __iter__(self):
# return iter([11,22,33,44])
yield 11
yield 22
yield 33
yield 44
yield 55
#
# # pass
obj = Foo()
print(obj.__iter__(),'你好啊')
obj.__iter__()
# obj.__iter__()
# obj.__iter__()
print('开始',type(li),obj.__dict__,'分开看',type(Foo),obj.__dict__,'难道是你',)
print(dir(obj))
print(dir(li))
for s in obj:
print(s)
# s.__iter__()
输出:
1
2
3
4
5
<generator object Foo.__iter__ at 0x000001B369A92F10> 你好啊
开始 <class 'list'> {} 分开看 <class 'type'> {} 难道是你
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
11
22
33
44
55
类的__iter__方法
class Row(object):
def __init__(self,data):
self.data = data
# return iter([11,22,33,44])
def __iter__(self):
yield '<div>'
yield '全部'
for item in self.data:
yield '<a>%s</a>' %item
yield '</div>'
yield 11
yield 22
yield 33
yield 44
yield 55
data_list = [
Row(['1.0以下','1.2-1.6']),
Row(['汽油','柴油','混合动力','电动']),
Row(['汽油1','柴油2','混合动力1','电动1']),
Row(['汽油1','柴油2','混合动力1','电动1'])
]
for row in data_list:
for field in row:
print(field)
输出:
<div>
全部
<a>1.0以下</a>
<a>1.2-1.6</a>
</div>
11
22
33
44
55
<div>
全部
<a>汽油</a>
<a>柴油</a>
<a>混合动力</a>
<a>电动</a>
</div>
11
22
33
44
55
<div>
全部
<a>汽油1</a>
<a>柴油2</a>
<a>混合动力1</a>
<a>电动1</a>
</div>
11
22
33
44
55
<div>
全部
<a>汽油1</a>
<a>柴油2</a>
<a>混合动力1</a>
<a>电动1</a>
</div>
11
22
33
44
55
测试:
li = [1,2,3]
for item in li:
print(item)
class Row(object):
def __init__(self,data):
self.data = data
def __iter__(self):
# return iter([11,22,33,44])
yield '<div>'
yield '全部'
for item in self.data:
yield "<a href='xxx'>%s</a>" %item
yield "</div>"
data_list =[
Row(['1升以下','1.1-1.6']),
Row(['汽油','柴油','混合动力','电动']),
]
for s in data_list:
print(s)
print('_'*88)
s.__iter__()
for field in s:
print(field)
输出:
1
2
3
<__main__.Row object at 0x000001E130D19F98>
________________________________________________________________________________________
<div>
全部
<a href='xxx'>1升以下</a>
<a href='xxx'>1.1-1.6</a>
</div>
<__main__.Row object at 0x000001E130D19FD0>
________________________________________________________________________________________
<div>
全部
<a href='xxx'>汽油</a>
<a href='xxx'>柴油</a>
<a href='xxx'>混合动力</a>
<a href='xxx'>电动</a>
</div>
写入自己的博客中才能记得长久