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>
posted @ 2021-04-16 21:18  ty1539  阅读(96)  评论(0编辑  收藏  举报