迭代器与生成器


迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式。。

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter() 和 next()

字符串,列表或元组对象都可用于创建迭代器:

实例(Python 3.0+)

>>>list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> print (next(it))
# 输出迭代器的下一个元素 1
>>> print (next(it))
# 输出迭代器的下一个元素 2

迭代器对象可以使用常规for语句进行遍历:

实例(Python 3.0+)

#!/usr/bin/python3
list=[1,2,3,4]
it = iter(list)
# 创建迭代器对象
for x in it:
print (x, end=" ")

执行以上程序,输出结果如下:

1 2 3 4

也可以使用 next() 函数:

实例(Python 3.0+)

#!/usr/bin/python3
import sys
# 引入 sys 模块
list=[1,2,3,4]
it = iter(list)
# 创建迭代器对象
while True:
  try:
    print (next(it))
  except StopIteration:
sys.exit()

执行以上程序,输出结果如下:

1
2
3
4

生成器

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行 next()方法时从当前位置继续运行。

以下实例使用 yield 实现斐波那契数列:

实例(Python 3.0+)

#!/usr/bin/python3
import sys
def fibonacci(n):
# 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True: if (counter > n):
return yield a a, b = b, a + b counter += 1
f = fibonacci(10)
# f 是一个迭代器,由生成器返回生成
while True: try:
print (next(f), end=" ")
except StopIteration:
sys.exit()

执行以上程序,输出结果如下:

0 1 1 2 3 5 8 13 21 34 55
 

笔记列表

  1. cowpea

    115***1355@qq.com

    来看一下有yield和没有yield的情况会对生成器了解多点:

    第一种:使用 yield

    #!/usr/bin/python3
    
    import sys
    
    def fibonacci(n,w=0): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
    if (counter > n):
    return
    yield a
    a, b = b, a + b
    print('%d,%d' % (a,b))
    counter += 1
    f = fibonacci(10,0) # f 是一个迭代器,由生成器返回生成 while True:
    try:
    print (next(f), end=" ")
    except :
    sys.exit()

    输出结果:

    0 1,1
    1 1,2
    1 2,3
    2 3,5
    3 5,8
    5 8,13
    8 13,21
    13 21,34
    21 34,55
    34 55,89
    55 89,144

    第二种:不使用 yield

    #!/usr/bin/python3
    
    import sys
    
    def fibonacci(n,w=0): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
    if (counter > n):
    return
    #yield a
    a, b = b, a + b
    print('%d,%d' % (a,b))
    counter += 1
    f = fibonacci(10,0) # f 是一个迭代器,由生成器返回生成 while True:
    try:
    print (next(f), end=" ")
    except :
    sys.exit()

    输出结果:

    1,1
    1,2
    2,3
    3,5
    5,8
    8,13
    13,21
    21,34
    34,55
    55,89
    89,144

    第二种没有yield时,函数只是简单执行,没有返回迭代器f。这里的迭代器可以用生成l列表来理解一下:

    >>> l = [i for i in range(0,15)]
    >>> print(l)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
    >>> m = (i for i in range(0,15))
    >>> print(m)
    <generator object <genexpr> at 0x104b6f258>
    >>> for g in m:
    ... print(g,end=', ')
    ...
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,

    这里的m就像上面的f一样,是迭代器。

    cowpea

    cowpea

    115***1355@qq.com

    1个月前 (07-27)

  2. ErikaEmma

    463***503@qq.com

    参考地址

    什么情况下需要使用 yield?

    一个函数 f,f 返回一个 list,这个 list 是动态计算出来的(不管是数学上的计算还是逻辑上的读取格式化),并且这个 list 会很大(无论是固定很大还是随着输入参数的增大而增大),这个时候,我们希望每次调用这个函数并使用迭代器进行循环的时候一个一个的得到每个 list 元素而不是直接得到一个完整的 list 来节省内存,这个时候 yield 就很有用。

    具体怎么使用 yield 参考:Python yield 使用浅析

    以斐波那契函数为例,我们一般希望从 n 返回一个 n 个数的 list:

    def fab(max):
    n, a, b = 0, 0, 1
    L = []
    while n < max:
    L.append(b)
    a, b = b, a + b
    n = n + 1
    return L

    上面那个 fab 函数从参数 max 返回一个有 max 个元素的 list,当这个 max 很大的时候,会非常的占用内存。

    一般我们使用的时候都是这个样子的,比如:

    f = fab(1000)
    while True:
    try:
    print (next(f), end=" ")
    except StopIteration:
    sys.exit()

    这样我们实际上是先生成了一个 1000 个元素的 list:f,然后我们再去使用这个 f。

    现在,我们换一个方法:

    因为我们实际使用的是 list 的遍历,也就是 list 的迭代器。那么我们可以让这个函数 fab 每次只返回一个迭代器——一个计算结果,而不是一个完整的 list:

    def fab(max):
    n, a, b = 0, 0, 1
    while n < max:
    yield b
    # print b
    a, b = b, a + b
    n = n + 1

    这样,我们每次调用fab函数,比如这样:

    for x in fab(1000):
    print(x)

    或者 next 函数之类的,实际上的运行方式是每次的调用都在 yield 处中断并返回一个结果,然后再次调用的时候再恢复中断继续运行。

最新文章

  1. C#设计模式-原型模式
  2. How to create vlan on Linux (with Cisco Catalyst Switch)
  3. 【转】段错误调试神器 - Core Dump详解
  4. tomcat 5.5 动态加载类
  5. Windows Azure Virtual Machine (32) 如何在Windows操作系统配置SFTP
  6. PHP程序z中xdebug工具简要使用方法
  7. php空心菱形
  8. Pull解析xml
  9. mongodb主从复制
  10. java中IO流的操作
  11. Js 的常用方法:页面跳转,Session,类继承
  12. iOS基本的发短信和打电话调用
  13. js理解
  14. linux下mysql的大小写是否区分设置
  15. mysql 字符集更改与导入数据
  16. ZOJ3774 Power of Fibonacci 斐波那契、二项式定理
  17. IntelliJ IDEA安装后需要必须做的一件事
  18. MVC爬取网页指定内容到数据库
  19. 无法在线安装Genymotion Eclipse插件,显示”There are no categoryzed items“
  20. Bettercap的安装和使用嗅探WIFI

热门文章

  1. 我的Android进阶之旅------>Android Studio使用statistics插件统计项目代码总行数
  2. 收藏:几种开源许可证的区别!——By 阮一峰制作
  3. 0601-Zuul构建API Gateway-API gateway简介、基础使用、路由配置、负载配置
  4. django Form表单的使用
  5. go——并发(二)
  6. Canvas:技术小结
  7. Python 一行代码实现并行
  8. Java并发之CyclicBarria的使用
  9. shell 学习一
  10. Linux网络IO函数以及TCP连接函数包装