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

一、列表推导式

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()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容