Python中迭代器和生成器的示例详解


本文摘自php中文网,作者黄舟,侵删。

迭代器


Iterable

定义

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

class Iterable(metaclass=ABCMeta):

 

    __slots__ = ()

 

    @abstractmethod

    def __iter__(self):

        while False:

            yield None

 

    @classmethod

    def __subclasshook__(cls, C):

        if cls is Iterable:

            if any("__iter__" in B.__dict__ for B in C.__mro__):

                return True

        return NotImplemented

由定义可知Iterable必然包含__iter__函数

Iterator

定义

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

class Iterator(Iterable):

 

    __slots__ = ()

 

    @abstractmethod

    def __next__(self):

        'Return the next item from the iterator. When exhausted, raise StopIteration'

        raise StopIteration

 

    def __iter__(self):

        return self

 

    @classmethod

    def __subclasshook__(cls, C):

        if cls is Iterator:

            if (any("__next__" in B.__dict__ for B in C.__mro__) and

                any("__iter__" in B.__dict__ for B in C.__mro__)):

                return True

        return NotImplemented

从定义可知Iterator包含__next____iter__函数,当next超出范围时将抛出StopIteration事件

类型关系

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#! /usr/bin/python

#-*-coding:utf-8-*-

 

from collections import Iterator,Iterable

 

# 迭代器

s = 'abc'

l = [1,2,3]

d=iter(l)

 

print(isinstance(s,Iterable)) # True

print(isinstance(l,Iterable)) # True

 

print(isinstance(s,Iterator)) # False

print(isinstance(l,Iterator)) # False

 

print(isinstance(d,Iterable)) # True

print(isinstance(d,Iterator)) # True

理论上你可以使用next()来执行__next__(),直到迭代器抛出StopIteration 实际上系统提供了for .. in ..的方式来解析迭代器

1

2

3

4

5

6

7

8

9

l = [1,2,3,4]

for i in l:

    print(i)

     

# 执行结果   

# 1

# 2

# 3

# 4

生成器 generator


生成器的本质是一个迭代器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#! /usr/bin/python

#-*-coding:utf-8-*-

 

from collections import Iterator,Iterable

 

s = (x*2 for x in range(5))

print(s)

print('Is Iterable:' + str(isinstance(s,Iterable)))

print('Is Iterator:' + str(isinstance(s,Iterator)))

 

for x in s:

    print(x)

 

# 执行结果   

# <generator object <genexpr> at 0x000001E61C11F048>

# Is Iterable:True

# Is Iterator:True

# 0

# 2

# 4

# 6

# 8

函数中如果存在yield 则该函数是一个生成器对象 在每一次执行next函数时该函数会在上一个yield处开始执行,并在下一个yield处返回(相当于return

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

def foo():

    print("First")

    yield 1

    print("Second")

    yield 2

 

f = foo()

print(f)

 

a = next(f)

print(a)

b = next(f)

print(b)

 

# <generator object foo at 0x0000020B697F50F8>

# First

# 1

# Second

# 2


实例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

#! /usr/bin/python

#-*-coding:utf-8-*-

 

def add(s,x):

    return s+x

 

def gen():

    for i in range(4):

        yield i

 

base = gen()

 

# 由于gen函数中存在yield,所以

# for 循环本质是创建了两个generator object,而非执行函数

# base = (add(i,10) for i in base)

# base = (add(i,10) for i in base)

for n in [1,10]:

    base = (add(i,n) for i in base)

 

 

# 这里才开始展开生成器

# 第一个生成器展开

# base = (add(i,10) for i in base)

# base = (add(i,10) for i in range(4))

# base = (10,11,12,13)

#

# 第二个生成器展开

# base = (add(i,10) for i in (10,11,12,13))

# base = (20,21,22,23)

print(list(base)) # [20,21,22,23]

以上就是Python中迭代器和生成器的示例详解的详细内容,更多文章请关注木庄网络博客!!

相关阅读 >>

Python函数学习的注意要点

iPythonPython区别

Python有double类型吗

Python什么时候用多进程编程

Python是什么?速读本文让你快速Python入门

Python tuple怎么用

Python怎么把列表转换为集合

Python判断字符类型怎么做

Python中tornado协程的使用详解(附实例)

有关Python的md5加密用法详解

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...