zoukankan      html  css  js  c++  java
  • day13——迭代器,生成器,列表推导式,生成器表达式

    迭代器

    可迭代对象

    内部含有__iter__方法的就是可迭代对象,遵循可迭代协议。

    可迭代协议:

    假如我们自己写了一个数据类型,希望这个数据类型里的东西也可以使用for被一个一个的取出来,那我们就必须满足for的要求。这个要求就叫做“协议”。

    可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法。

    dir:查看对象所有方法

    # print(dir('123')) # '__iter__'----------------------------True
    # print('__iter__' in dir([1, 2, 3]))---------------------------True
    # print('__iter__' in dir({'name':'alex'}))---------------------------True
    # print('__iter__' in dir({'name'}))---------------------------True
    # print('__iter__' in dir((1, 2, 3)))---------------------------True
    # print('__iter__' in dir(1)) --------------------------- False
    # print('__iter__' in dir(True))--------------------------- False

    什么是迭代器?

      可迭代对象通过__iter__()可以转换成迭代器,满足迭代器协议。

      内部含有__iter__且__next__方法的就是迭代器。

    # l = [1, 2, 3]
    # l_obj = l.__iter__()
    # print(l_obj)

    迭代器的取值两种方法:

    l = [1, 2, 3]
    l_obj = l.__iter__()
    print(l_obj)------------------<list_iterator object at 0x000002B84DE73748>
    方法一:__next__()
    print(l_obj.__next__())-------------1
    print(l_obj.__next__())-------------2
    print(l_obj.__next__())-------------3
    
    方法二 for循环
    for i in l_obj:
        print(i)
    print('__next__' in dir(l_obj))
    -------------1
            2
            3
            True

    第二种判断方法:

    from collections import Iterable
    from collections import Iterator
    print(isinstance('123', Iterable))
    print(isinstance('123', Iterator))

    迭代器:

      1,节省内存

      2,满足惰性机制

      3,取值过程单向不可逆(一条路走到黑)

     

    迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。

    for循环,能遍历一个可迭代对象,他的内部到底进行了什么?

    • 将可迭代对象转化成迭代器。(可迭代对象.__iter__())
    • 内部使用__next__方法,一个一个取值。
    • 加了try异常处理功能,取值到底后自动停止,防止报错。

    用while循环模拟for循环:

    l = [1, 2, 3, 4, 5]
    l_obj = l.__iter__()
    while True:
        try:
            print(l_obj.__next__())
        except Exception:
            break
    ------------1
                2
                3
                4
                5

    生成器

    生成器本质也是迭代器,生成器是自己用python构建的迭代器

      1,通过生成器函数构建

      2,通过生成器推导式构建。

    def func1():
        print(666)
        return 222
    ret = func1()
    print(ret)----------------666
                                        222
    
    def func1():
        print(11)
        print(333)
        yield 222
        print(666)
        yield 777
    g_obj = func1()  # 生成器对象 generator object
    print(g_obj.__next__())
    print(g_obj.__next__())
    --------------------------11
                                        333
                                        222
                                        666
                                        777  
    def cloth1():
        for i in range(1,10001):
            print('衣服%s' % i)
    cloth1()  
    
    打印''衣服+序号'’直到----------衣服10000
    
    
    def cloth2():
        for i in range(1,10001):
            yield '衣服%s' % i
    
    g = cloth2()
    for i in range(1,51):
        print(g.__next__())
    
    for i in range(1, 151):
        print(g.__next__())
    打印''衣服+序号''   一直打印到----衣服200

    next --- send

    def func1():
        count = yield 222
        print(count)
        yield 777
        yield 888
    g_obj = func1()  # 生成器对象 generator object
    print(g_obj.__next__())
    print(g_obj.send('wusir'))
    -----------------222
                            wusir
                            777        

      1,send具有next功能

      2,send可以给上一个yield传值。

      3,第一个取值不会使用send

      4,最后一个yield不会得到send的值、

    列表推导式:

      能用列表推导式完成的,用python代码都可以完成。用一句话构建一个你想要的列表。

      优点:简单,稍微难理解

      缺点:不能用debug

    li = []
    for i in range(1, 12):
        li.append(i)
    print(li)----------------[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    li = [i for i in range(1, 12)]
    [ 变量(加工后的变量) for 变量 in 可迭代对象 ]  遍历模式
    print(li)-------------------[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    li = []
    for i in range(1, 12):
        li.append('python%s期' % i)
    print(li)
    ---------------['python1期', 'python2期', 'python3期', 'python4期', 'python5期',
     'python6期', 'python7期', 'python8期', 'python9期', 'python10期', 'python11期']
    [变量(加工后的变量) for 变量 in 可迭代对象]    遍历模式
    [变量(加工后的变量) for 变脸 in 可迭代对象 if 判断]  帅选模式
    
    l1 = [i for i in range(1, 101) if i % 2 == 0]
    print(l1)-------------【2,4,6,8·····1001,筛选,100以内所有奇数。
    
    l2 = [i for i in range(1, 101) if i % 2 == 1]
    l2 = [i for i in range(1, 101, 2)]
    
    print(l2)--------【1,3,5,7,```````992,10以内所有数的平方。 [1,4,9,16,```````100]
    
    print([i*i for i in range(1, 11)])
    
     
    
    3,将100以内所有内被三整除的数留到列表中。
    
    ①
    
    print([i for i in range(1,101) if i % 3 == 0])
    
    ②
    g = (i*i for i in range(1, 11))
    print(g.__next__())-------------1
    print(g.__next__())-------------4
    print(g.__next__())-------------9
    print(g.__next__())-------------16
    print(g.__next__())-------------25
    ③
    g = (i*i for i in range(1, 11))
    for i in g:
        print(i)

    列表推导式 :简单明了,但是占内存

    生成器表达式:节省内存,不易看出

    30以内所有能被3整除的数的平方
    print([i*i for i in range(1, 31) if i % 3 ==0])
    -------------[9, 36, 81, 144, 225, 324, 441, 576, 729, 900]
    
    names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
             ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
    l3 = [ name for i in names for name in i if name.count('e') == 2]
    print(l3)-------------------['Jefferson', 'Wesley', 'Steven', 'Jennifer']
    
    # mcase = {'a': 10, 'b': 34}
    # mcase_frequency = {mcase[k]: k for k in mcase}
    # print(mcase_frequency)------------{10: 'a', 34: 'b'}



    day13作业默写
    1,整理今天的博客,写课上代码,整理流程图。
    2,用列表推导式做下列小题
    (1)过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
    li = [i.upper() for i in ['dfsf','fskjf','fs','f'] if len(i) < 3]
    print(li)



    (2)求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元祖列表
    li = [(x,y) for x in range(0,6) for y in range(0,6) if x % 2 == 0 if y % 2 == 1]
    print(li)



    (3)求M中3,6,9组成的列表
    M = [[1,2,3],[4,5,6],[7,8,9]]
    li = [i[-1] for i in M]
    print(li)



    (4)求出50以内能被3整除的数的平方,并放入到一个列表中。
    li = [i*i for i in range(50) if i % 3 == 0]
    print(li)


    (5)构建一个列表:['python1期', 'python2期', 'python3期', 'python4期', 'python6期', 'python7期', 'python8期', 'python9期', 'python10期']
    li = ['python%s期'%i for i in range(1,11)]
    print(li)


    (6)构建一个列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
    li = [(x,y) for x in range(6) for y in range(7) if x == y - 1]
    print(li)


    (7)构建一个列表:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
    li = [i for i in range(19) if i % 2 == 0]
    print(li)


    (8)有一个列表l1 = ['alex', 'WuSir', '老男孩', '太白']将其构造成这种列表['alex0', 'WuSir1', '老男孩2', '太白3']
    l1 = ['alex', 'WuSir', '老男孩', '太白']
    li = [l1[i] + str(i) for i in range(len(l1))]
    print(li)


    (9)有以下数据类型:
    x = {
    'name':'alex',
    'Values':[{'timestamp':1517991992.94,
    'values':100,},
    {'timestamp': 1517992000.94,
    'values': 200,},
    {'timestamp': 1517992014.94,
    'values': 300,},
    {'timestamp': 1517992744.94,
    'values': 350},
    {'timestamp': 1517992800.94,
    'values': 280}
    ],}
    将上面的数据通过列表推导式转换成下面的类型:
    [[1517991992.94, 100], [1517992000.94, 200], [1517992014.94, 300], [1517992744.94, 350], [1517992800.94, 280]]
    ①
    li = [[x['Values'][i]['timestamp'],x['Values'][i]['values']]for i in range(len(x['Values']))]
    print(li)
    
    ②
    lst=[[i['timestamp'],i['values']] for i in x['Values']]
    print(lst)





  • 相关阅读:
    14丨指令的本质是什么
    Nodejs的测试和测试驱动开发
    javascript的Mixins
    踏破铁鞋无觅处,从AsyncTask学Android线程池
    Android自定义视图四:定制onMeasure强制显示为方形
    Android自定义视图三:给自定义视图添加“流畅”的动画
    Android自定义视图二:如何绘制内容
    Android自定义视图一:扩展现有的视图,添加新的XML属性
    属性动画和Activity、Fragment过渡动画等
    RecyclerView怎么能没有ItemClickListener?加一个!
  • 原文地址:https://www.cnblogs.com/-li926/p/9483779.html
Copyright © 2011-2022 走看看