初学python之解析式

发布时间:2019-09-16 07:39:23编辑:auto阅读(1609)


    解析式

     

    其目的主要用来减少编程行数,并减少栈帧从而达到代码优化的效果

     

    In [6]: [i ** 2 for i in range(11)]

    Out[6]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

     

    将生产环节元素表达式放在最前面

     

    列表解析语法

    [返回值 for 元素 可迭代对象if条件]

     

    使用中括号表示,内部for为循环跟if条件可选,返回一个新的列表

    这样可以简化编程中书写并且减少了栈帧,从而达到优化效果

     

    例:对i进行取模

    In [23]: [ i for i in range(1,10) if i % 2 == 0]

    Out[23]: [2, 4, 6, 8]

     

    解析式中不能使用else 和 elif 所以需要用or 和 and来代替

    In [4]: [i for i in range(20) if i %2 == 0 and i%3 == 0]

    Out[4]: [0, 6, 12, 18]

     

    使用or/ not

    In [5]: [i for i in range(20) if i %2 == 0 or noti % 2== 0]

    Out[5]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12, 13, 14, 15, 16, 17, 18, 19]

     

    使用and / not

    In [11]: [i for i in range(20) if i % 2 ==0 andnot i % 3]

    Out[11]: [0, 6, 12, 18]

    可以理解为:

    In [13]: [i for i in range(20) if i % 2 ==0 andnot i % 3 != 0]

    Out[13]: [0, 6, 12, 18]

     

    推导式的多重过滤

    使用and进行代替多个if:if:if,对多重邓加进行代替

     

     

    for i in iter1:

        for j in iter2:

            lst.append(expr)

     

    等价于:

    In[14]: [expr for i in iter1 for j in iter2]

     

     

    例:

    1.  

    In [14]: [ (x,y) for x in 'abc' for y in range(3)]

    Out[14]:

    [('a', 0),

    ('a', 1),

    ('a', 2),

    ('b', 0),

    ('b', 1),

    ('b', 2),

    ('c', 0),

    ('c', 1),

    ('c', 2)]

     

    等价于:

    In [21]: for i in 'abc':

        ...:     fory in range(3):

        ...:         lst.append((i,y))

      

     

    In [26]: [{x:y} for x in "abcde" for yin range(3)]

    Out[26]:

    [{'a': 0},

    {'a': 1},

    {'a': 2},

    {'b': 0},

    {'b': 1},

    {'b': 2},

    {'c': 0},

    等价于:

    In [34]: for i in "abc":

        ...:     forx in range(3):

        ...:         lst.append({i:x})

     

     

    在语句上第三个最方便,但是第一条最容易理解:

    In [36]: [ (i,j) for i in range(7) if i > 4for j in range(20,25) if j > 23   ]

    Out[36]: [(5, 24), (6, 24)]

     

    In [37]: [(i,j) for i in range(7) for j inrange(20,25) if i > 4 if j > 23]

    Out[37]: [(5, 24), (6, 24)]

     

    In [39]: [(i,j) for i in range(7) for j inrange(20,25) if i > 4 and  j > 23]

    Out[39]: [(5, 24), (6, 24)]

     

    求99乘法表

     

    [print ('{}*{}={:<3}{}'.format(j,i,i*j,'\n' ifi == j else ''),end = "") for i in range(1,10) for j in range(1,i+1)]

     

     


    生成器表达式

    与解析式一样,只不过将中括号改为小括号

    In [2]: a = (n for n in range(10))

    In [3]: a

    Out[3]: <generator object <genexpr> at 0x7fed4ea1cfc0>

     

    In [5]: next(a)

    Out[5]: 0

    In [6]: next(a)

    Out[6]: 1

    In [7]: next(a)

    Out[7]: 2

     

    迭代中,只能使用一次,当获取后则直接将其销毁,不再保留至内存空间中

    使用next(a)的方法,必须一定是可迭代对象

     

     

    使用生成器的好处:

       ·延迟计算

       ·返回迭代器,可以进行迭代

       ·从签到后走完一遍,不能回头

     

     

    例:

    使用print进行观察

    In [8]: a = (print("{}".format(i+1))  for i in range(2))

    In [9]: print(a)

    <generator object <genexpr> at0x7fed51641f10>

     

    In [10]: b = next(a)

    1

    In [11]: b = next(a)

    2

    In [12]: b = next(a)

    ---------------------------------------------------------------------------

    StopIteration                             Traceback(most recent call last)

    <ipython-input-12-78fca016cc6c> in<module>()

    ----> 1 b = next(a)

    StopIteration:

     

     

     

    生成器和列表解析式对比

     

    立即生成和延后计算,可以嵌套在列表解析式中从返回值来讲,更节省内存,生成器则全部生成并返回

    生成器没有数据,占用内存极少,使用的时候逐个返回

    列表需要占用更多的内存

     

    计算速度

    生成器耗时间非常短,列表解析消耗时间略长

    生成器本身是一个迭代器

     

    速度对比

    In[14]: %timeit [x for x in range(500)]

    18 μs ± 102 ns per loop (mean± std. dev. of 7 runs, 100000 loops each)

    In[15]: %timeit (x for x in range(500))

    741 ns± 7.58 ns perloop (mean ± std. dev. of 7 runs, 1000000 loops each)

     

     

     

    集合解析式

    将返回值for作为可迭代对象通过if条件换位,

    将括号换至为大伙靠,生成后立刻返回一个集合

    In [19]: {(x,x+1) for x in range(10)}

    Out[19]:

    {(0, 1),

    (1, 2),

    (2, 3),

    (3, 4),

    (4, 5),

    (5, 6),

    (6, 7),

    (7, 8),

    (8, 9),

    (9, 10)}

     

     

    字典解析式:

    In [25]: {chr(0x41+x):x**2 for x in range(10) }

    Out[25]:

    {'A': 0,

    'B': 1,

    'C': 4,

    'D': 9,

    'E': 16,

    'F': 25,

    'G': 36,

    'H': 49,

    'I': 64,

    'J': 81}

     

    In [26]: {str(x):y for x in range(3) for y inrange(4)}

    Out[26]: {'0': 3, '1': 3, '2': 3}

     

     

     

     

    内建函数

     

    iter 将一个可迭代对象封装为一个迭代器

    a = iter(range(5))

     

    迭代器对象,迭代器本身是可迭代的,所以说可以通过iter方法将可迭代对象封装为迭代器然后通过next方法进行迭代

     

    zip 拉链函数

    将多个可迭代函数合并在一起,返回一个迭代器,将每次不同对象中取到的元素合并到一个元组中

    In [40]: list(zip(range(10),range(10)))

    Out[40]:

    [(0, 0),

    (1, 1),

    (2, 2),

    (3, 3),

    (4, 4),

    (5, 5),

    (6, 6),

    (7, 7),

    (8, 8),

    (9, 9)]

     

     

    zip木桶原理,取当前最短的,并不再继续

    In [41]: list(zip(range(10),range(10),range(5)))

    Out[41]: [(0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3,3), (4, 4, 4)]

     

     

    如果某一个值超出,则只选择最短的值,不会再进行多次选取

    In [42]: list(zip(range(10),range(10),range(50)))

    Out[42]:

    [(0, 0, 0),

    (1, 1, 1),

    (2, 2, 2),

    (3, 3, 3),

    (4, 4, 4),

    (5, 5, 5),

    (6, 6, 6),

    (7, 7, 7),

    (8, 8, 8),

    (9, 9, 9)]

     

    In [43]: list(zip(range(10),range(10),range(3)))

    Out[43]: [(0, 0, 0), (1, 1, 1), (2, 2, 2)]

     


关键字