第六章 迭代器与生成器&列表推倒式

一、列表推导式

1、概述

列表推导式提供了从序列创建列表的简单途径。

2、回顾

只能生成简单的列表

print(list(range(1,11)))

3、需求

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

4、实现

  1. 循环生成列表

    li = []
    for i in range(1, 11):
        li.append(pow(i, 2))
    print(li)
    

    缺点:循环比较繁琐

  2. 列表生成式

    作用

    列表推导式提供了从序列创建列表的简单途径。

  • 一般形式

    li2 = [x * x for x in range(1, 11)]
    print(li2)
    
  • 一般形式加判断

    if 子句作为过滤器

    >>> vec = [2, 4, 6]
    >>> [3*x for x in vec if x > 3]
    [12, 18]
    li3 = [x for x in range(1, 11) if x % 2 == 0]
    print(li3)
    
  • 多层循环

    li4 = [x + y for x in "ABC" for y in "123"]
    print(li4)
    

    拆分

    for x in "ABC":
        for y in "123":
            ret = x + y
    
  • 列表嵌套

    #输出每个值 并将每个值2次方
    vec = [2, 4, 6]
    [[x, x**2] for x in vec]
    [[2, 4], [4, 16], [6, 36]]
    

5、案例 矩阵转换

  • 以下实例展示了3X4的矩阵列表:

    >>> matrix = [
    ...     [1, 2, 3, 4],
    ...     [5, 6, 7, 8],
    ...     [9, 10, 11, 12],
    ... ]
    
  • 以下实例将3X4的矩阵列表转换为4X3列表:

    >>> [[row[i] for row in matrix] for i in range(4)]
    [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
    

    另外一种实现方法:

    >>> transposed = []
    >>> for i in range(4):
    ...     # the following 3 lines implement the nested listcomp
    ...     transposed_row = []
    ...     for row in matrix:
    ...         transposed_row.append(row[i])
    ...     transposed.append(transposed_row)
    ...
    >>> transposed
    

二、字典推导式

可能你见过列表推导时,却没有见过字典推导式,在2.7中才加入的:

格式:

d = {key: value for (key, value) in iterable}

示例

d = {key: value for key, value in [('a','a'),('b','b')]

三、可迭代对象

1、概念

可以直接作用于for循环的对象统称为可迭代对象(Iterable)

可以用isinstance()去判断一个对象是否是Iterable对象

2、可以直接作用于for循环的数据类型

  • 集合数据类型(list、tuple、dict、set、string)

  • generator
    a、生成器
    b、带yield的generator function

      Iterable表示可迭代类型
    
  • 引入方法判断是否为 Iterable 可迭代对象

    from collections import Iterable

from collections import Iterable
# 格式
# isinstance(obj, type):判断obj是否属于type类型

print(isinstance([], Iterable))
print(isinstance((), Iterable))
print(isinstance({}, Iterable))
print(isinstance("", Iterable))
print(isinstance(range(10), Iterable))
print(isinstance(100, Iterable))

四、迭代器

1、概念

1、可以被next()函数调用并返回一个值的对象为迭代器对象
2、迭代器不但可以用于for,还可以用于next()

2、使用

使用 iter函数 变成Iterator对象

  • from collections import Iterator

实例:

#转成Iterator对象
li = [1,2,3,4,5]
g = iter(li)
print(g, type(g))
print(next(g))
print(next(g))

判断是否为迭代器

可以被next()函数调用并不断返回下一个值的对象称为迭代器(Iterator对象)
可以使用isinstance()函数判断一个对象是否是Iterator对象

from  collections import Iterator

print(isinstance([], Iterator))
print(isinstance((), Iterator))
print(isinstance({}, Iterator))
print(isinstance("", Iterator))
print(isinstance((x for x in range(10)), Iterator))

注意:

  1. 迭代是Python最强大的功能之一,是访问集合元素的一种方式。。
  2. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
  3. 迭代器有两个基本的方法:iter()next()
  4. 不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后跑出一StopIteration错误表示无法继续返回下一个值

2、为什么list、tuple、dict、string、set等数据类型不是Iterator?

Iterator对象表示的是一个流数据,Iterator对象可以被next()调用并返回一个数据,直到抛出StopIteration异常错误则停止。可以把数据流看成一个有序的序列,但是不确定这个序列的长度,只能通过next()函数不断计算求值,Iterator可以表示一个无限大的数据流,而list等永远不可能存储无限的数据

五、生成器

1、概述

在 Python 中,使用了 yield 的函数被称为生成器(generator)。生成器也实现了迭代器的功能

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

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

调用一个生成器函数,返回的是一个迭代器对象。

2、注意

  • 函数时顺序执行,遇到return语句后者最后一行代码就返回

  • 如果想让一个函数变为生成器函数,只需将函数中的return改为yield

  • 执行生成器函数不会执行函数代码,得到一个生成器

  • 在每次调用next()的时候,会执行生成器函数,遇到yield语句就返回,如果再次执行next()

3、实现

  • 使用列表推倒式实现

    #普通列表 消耗资源
    mylist = [x for x in range(100000)]
    for i in mylist:
        print(i)
    #对比执行效率
    #生成器  节省资源
    mylist = (x for x in range(100000))
    for i in mylist:
        print(i) 
    
  • 使用函数实现

    1. yield
    2. Next()

    使用yield关键字修饰的值 下面的代码不会再执行 只有再次调用next函数的时候 会再次执行

    #没有生成器的go方法 调用的时候一口气都跑完  消耗资源
    def go():
        print(1)
        print(2)
        print(3)
    #有生成的函数 可以实现 next一次 走一次
    def go():
        print(1)
        yield 10 #执行print1,返回10,next
        print(2)
        yield 20#执行print2,返回20,next
        print(3)
        yield 30#执行print3,返回30,next
    
    def createlist():
        for i  in range(100):
            print(i)
            yield  i
    
    X=createlist()
    print(type(X))
    next(X)
    next(X)
    next(X)
    next(X)
    

4、使用 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()

你可能感兴趣的:(第六章 迭代器与生成器&列表推倒式)