美文网首页大数据 爬虫Python AI SqlPython小哥哥
Python教程·迭代、可迭代对象、迭代器与生成器详解!

Python教程·迭代、可迭代对象、迭代器与生成器详解!

作者: 14e61d025165 | 来源:发表于2019-03-18 14:54 被阅读0次

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

    只要是可迭代对象(Iterable),就可以通过for循环来遍历,这种遍历我们称为迭代。

    也就是说所有可作用于for循环的对象都是可迭代对象(Iterable)。

    那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:

    >>> from collections import Iterable
    >>> isinstance(123,Iterable)            # Integer 不可迭代
    False
    >>> isinstance('abc',Iterable)          # String 可迭代
    True
    >>> isinstance([1,2,3],Iterable)        # List 可迭代
    True
    >>> isinstance(('a','b','c'),Iterable)  # Tuple 可迭代
    True
    >>> isinstance({'name':'Arno','Job':'Ops'},Iterable)    # Dictionary 可迭代
    True
    

    dict 迭代说明
    默认情况下,dict迭代的是key:

    >>> d = {'Name':'Arno','Born':1993,'Job':'Ops'}
    >>> for k in d:
    ...     print(k)
    ... 
    Name
    Born
    Job
    

    如果要迭代value,可以用for value in d.values():

    for v in d.values():
    ... print(v)
    ...
    Arno
    1993
    Ops
    如果要同时迭代key和value,可以用for k, v in d.items():

    >>> for k,v in d.items():
    ...     print('key:', k, '\t', 'value:', v)
    ... 
    key: Name    value: Arno
    key: Born    value: 1993
    key: Job     value: Ops
    

    知识扩展

    在Python中,List元素是有索引的,那么如何实现类似Java那样的下标循环?

    方法一,通过len()方法取得列表长度,再结合range()方法实现索引下标循环:

    >>> L = ['a','b','c']
    >>> for i in range(len(L)):
    ...     print(i, L[i])
    ... 
    0 a
    1 b
    2 c
    

    方法二,Python内置的enumerate函数可以把一个list变成 索引-元素 对,这样就可以在for循环中同时迭代索引和元素本身:

    for i,v in enumerate(L):
    ... print(i, v)
    ...
    0 a
    1 b
    2 c
    iterator(迭代器)
    迭代器是一个可以记住遍历的位置的对象。

    迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束;

    迭代器只能往前不会后退;

    迭代器有两个基本的方法:

    iter()

    next()

    可以通过 collections 模块的 Iterator 类型判断一个对象是否是迭代器:

    from collections import Iterator
    isinstance([1,2,3], Iterator)
    False
    isinstance({'Name':'Arno','Born':1993,'Job':'Ops'}, Iterator)
    False
    isinstance('abc', Iterator)
    False
    isinstance(iter([1,2,3]), Iterator) # iter()创建迭代器对象

    True

    isinstance((x for x in range(10)), Iterator) # 生成器
    True
    可以看出,生成器(generator)都是迭代器(Iterator)对象,但String、List、Tuple、Dict虽然是可迭代对象(Iterable),却不是迭代器(Iterator)。

    当然,String、List、Tuple、Dict等可迭代对象都可用于创建迭代器:

    L = [1,2,3]
    it = iter(L)
    print(next(it))
    1
    print(next(it))
    2
    print(next(it))
    3
    print(next(it)) # 没有值可返回时,抛异常 StopIteration
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    StopIteration

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

    L = [1,2,3]
    it = iter(L)
    for x in it:
    ... print(x, end=" ")
    ...
    1 2 3
    也可以使用 next() 函数:

    import sys
    L = [1,2,3]
    it = iter(L)
    while True:
    ... try:
    ... print(next(it))
    ... except StopIteration:

    for i in range(len(L)):
    ... print(i, L[i])
    ...
    0 a
    1 b
    2 c
    ```
    方法二,Python内置的enumerate函数可以把一个list变成 索引-元素 对,这样就可以在for循环中同时迭代索引和元素本身:

    >>> for i,v in enumerate(L):
    ... print(i, v)
    ...
    0 a
    1 b
    2 c
    iterator(迭代器)
    迭代器是一个可以记住遍历的位置的对象。

    迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束;

    迭代器只能往前不会后退;

    迭代器有两个基本的方法:

    iter()

    next()

    可以通过 collections 模块的 Iterator 类型判断一个对象是否是迭代器:

    >>> from collections import Iterator
    >>> isinstance([1,2,3], Iterator)
    False
    >>> isinstance({'Name':'Arno','Born':1993,'Job':'Ops'}, Iterator)
    False
    >>> isinstance('abc', Iterator)
    False
    >>> isinstance(iter([1,2,3]), Iterator) # iter()创建迭代器对象
    True
    >>> isinstance((x for x in range(10)), Iterator) # 生成器
    True
    可以看出,生成器(generator)都是迭代器(Iterator)对象,但String、List、Tuple、Dict虽然是可迭代对象(Iterable),却不是迭代器(Iterator)。

    当然,String、List、Tuple、Dict等可迭代对象都可用于创建迭代器:

    >>> L = [1,2,3]
    >>> it = iter(L)
    >>> print(next(it))
    1
    >>> print(next(it))
    2
    >>> print(next(it))
    3
    >>> print(next(it)) # 没有值可返回时,抛异常 StopIteration
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    StopIteration
    >>>
    迭代器对象常使用for语句进行遍历:

    >>> L = [1,2,3]
    >>> it = iter(L)
    >>> for x in it:
    ... print(x, end=" ")
    ...
    1 2 3
    也可以使用 next() 函数:

    >>> import sys
    >>> L = [1,2,3]
    >>> it = iter(L)
    >>> while True:
    ... try:
    ... print(next(it))
    ... except StopIteration:
    ... sys.exit()
    ...
    1
    2
    3
    generator(生成器)
    创建生成器的方法:

    使用了 yield 语句的函数
    Generator 是一个用于创建迭代器的简单而强大的工具。 它们的写法类似标准的函数,但当它们要返回数据时会使用 yield 语句。 每次对生成器调用 next() 时,它会从上次离开位置恢复执行(它会记住上次执行语句时的所有数据值)。

    使用生成器表达式,就是把一个 列表生成式 的[]改成()
    某些简单的生成器可以写成简洁的表达式代码,所用语法类似列表推导式,将外层为圆括号而非方括号。 这种表达式被设计用于生成器将立即被外层函数所使用的情况。 生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存。

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

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

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

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

    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()
    列表生成式
    列表生成式(List Comprehensions)也叫列表推导式,提供了一个更简单的创建列表的方法。

    常见的用法:

    是把某种操作应用于序列或可迭代对象的每个元素上,然后使用其结果来创建列表;

    或者通过满足某些特定条件元素来创建子序列;

    例如,创建一个平方列表,像这样

    squares = []
    for x in range(10):
    ... squares.append(x2)
    L = [1,2,3]
    >>> it = iter(L)
    >>> for x in it:
    ... print(x, end=" ")
    ...
    1 2 3
    也可以使用 next() 函数:

    >>> import sys
    >>> L = [1,2,3]
    >>> it = iter(L)
    >>> while True:
    ... try:
    ... print(next(it))
    ... except StopIteration:
    ... sys.exit()
    ...
    1
    2
    3
    generator(生成器)
    创建生成器的方法:

    使用了 yield 语句的函数
    Generator 是一个用于创建迭代器的简单而强大的工具。 它们的写法类似标准的函数,但当它们要返回数据时会使用 yield 语句。 每次对生成器调用 next() 时,它会从上次离开位置恢复执行(它会记住上次执行语句时的所有数据值)。

    使用生成器表达式,就是把一个 列表生成式 的[]改成()
    某些简单的生成器可以写成简洁的表达式代码,所用语法类似列表推导式,将外层为圆括号而非方括号。 这种表达式被设计用于生成器将立即被外层函数所使用的情况。 生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存。

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

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

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

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

    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()
    列表生成式
    列表生成式(List Comprehensions)也叫列表推导式,提供了一个更简单的创建列表的方法。

    常见的用法:

    是把某种操作应用于序列或可迭代对象的每个元素上,然后使用其结果来创建列表;

    或者通过满足某些特定条件元素来创建子序列;

    例如,创建一个平方列表,像这样

    >>> squares = []
    >>> for x in range(10):
    ... squares.append(x
    2)
    ...
    squares
    it = iter(L)
    >>> for x in it:
    ... print(x, end=" ")
    ...
    1 2 3
    也可以使用 next() 函数:

    >>> import sys
    >>> L = [1,2,3]
    >>> it = iter(L)
    >>> while True:
    ... try:
    ... print(next(it))
    ... except StopIteration:
    ... sys.exit()
    ...
    1
    2
    3
    generator(生成器)
    创建生成器的方法:

    使用了 yield 语句的函数
    Generator 是一个用于创建迭代器的简单而强大的工具。 它们的写法类似标准的函数,但当它们要返回数据时会使用 yield 语句。 每次对生成器调用 next() 时,它会从上次离开位置恢复执行(它会记住上次执行语句时的所有数据值)。

    使用生成器表达式,就是把一个 列表生成式 的[]改成()
    某些简单的生成器可以写成简洁的表达式代码,所用语法类似列表推导式,将外层为圆括号而非方括号。 这种表达式被设计用于生成器将立即被外层函数所使用的情况。 生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存。

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

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

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

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

    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()
    列表生成式
    列表生成式(List Comprehensions)也叫列表推导式,提供了一个更简单的创建列表的方法。

    常见的用法:

    是把某种操作应用于序列或可迭代对象的每个元素上,然后使用其结果来创建列表;

    或者通过满足某些特定条件元素来创建子序列;

    例如,创建一个平方列表,像这样

    >>> squares = []
    >>> for x in range(10):
    ... squares.append(x**2)
    ...
    >>> squares
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    可以改为

    list(map(lambda x: x2, range(10)))
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    it = iter(L)
    >>> while True:
    ... try:
    ... print(next(it))
    ... except StopIteration:
    ... sys.exit()
    ...
    1
    2
    3
    generator(生成器)
    创建生成器的方法:

    使用了 yield 语句的函数
    Generator 是一个用于创建迭代器的简单而强大的工具。 它们的写法类似标准的函数,但当它们要返回数据时会使用 yield 语句。 每次对生成器调用 next() 时,它会从上次离开位置恢复执行(它会记住上次执行语句时的所有数据值)。

    使用生成器表达式,就是把一个 列表生成式 的[]改成()
    某些简单的生成器可以写成简洁的表达式代码,所用语法类似列表推导式,将外层为圆括号而非方括号。 这种表达式被设计用于生成器将立即被外层函数所使用的情况。 生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存。

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

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

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

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

    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()
    列表生成式
    列表生成式(List Comprehensions)也叫列表推导式,提供了一个更简单的创建列表的方法。

    常见的用法:

    是把某种操作应用于序列或可迭代对象的每个元素上,然后使用其结果来创建列表;

    或者通过满足某些特定条件元素来创建子序列;

    例如,创建一个平方列表,像这样

    >>> squares = []
    >>> for x in range(10):
    ... squares.append(x
    2)
    ...
    >>> squares
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    可以改为

    >>> list(map(lambda x: x**2, range(10)))
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    等价于

    列表推导式,更加简洁易读

    [x**2 for x in range(10)]
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    增加特定条件

    [x**2 for x in range(10) if x % 2 != 0]
    [1, 9, 25, 49, 81]
    创建为生成器

    (x**2 for x in range(10) if x % 2 != 0)
    <generator object <genexpr> at 0x7f076f06e990>
    知识扩展
    lambda 表达式
    lambda 表达式(有时称为 lambda 构型)被用于创建匿名函数。

    表达式 lambda parameters: expression 会产生一个函数对象 。 该未命名对象的行为类似于用以下方式定义的函数:

    def <lambda>(parameters):
    return expression
    注意:通过 lambda 表达式创建的函数不能包含语句或标注。

    map() 高阶函数
    接收两个参数,一个是函数,一个是可迭代对象(Iterable),map将传入的函数依次作用到序列的每个元素,并把结果作为新的iterator(迭代器)返回。

    总结
    迭代(iteration)是访问集合元素的一种方式;

    迭代器(iterator)对象一定是可迭代对象,反之则不一定;

    可迭代对象(Iterable)不一定是迭代器;
    例如list、dict、str等集合数据类型是可迭代对象,但不是迭代器,但是它们可以通过iter()函数生成一个迭代器对象。

    生成器(generator)对象既是可迭代对象也是迭代器;

    遍历方式

    迭代器、生成器和可迭代对象都可以用for循环去迭代

    生成器和迭代器还可以被next()方函数调用并返回下一个值

    相关文章

      网友评论

        本文标题:Python教程·迭代、可迭代对象、迭代器与生成器详解!

        本文链接:https://www.haomeiwen.com/subject/vjnvmqtx.html