吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5609|回复: 13
收起左侧

[Python 转载] 【笔记】Python之解析式详解

  [复制链接]
xian54966 发表于 2019-2-21 12:15
本帖最后由 xian54966 于 2019-2-21 12:21 编辑

目录

  1. 解析式的简单介绍
  2. 列表解析式
  3. 字典解析式
  4. 集合解析式

一、解析式简单介绍

  推导式:Comprehensions(又称解析式),是Python的一种独有特性。推导式是可以从一个数据序列构建另一个新的数据序列的结构体。 共有三种推导,在Python2和3中都有支持:
  a. 列表解析 # Python2只有列表解析
  b.生成器解析 # Python3特有
  c. 集合解析 # Python3特有
  d.字典解析 # Python3特有
解析式的作用:
  a. 修改可迭代对象
  b. 过滤可迭代对象

二、列表解析式

  列表解析的一般形式:

[expression for item in iterable]  #[表达式 for 元素 可迭代对象]

  接下来看几个示例:


In[23]: [2 ** n for n in range(10)]
Out[23]: [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]

In[24]: def inc(x):
    ...:     return x + 1
    ...: 

In[25]: [inc(x) for x in range(10)]
Out[25]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

In[26]: [0 for x in range(10)]
Out[26]: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

In[27]: def non_return(x):
    ...:     pass
    ...: 
In[28]: [non_return(x) for x in range(10)]
Out[28]: [None, None, None, None, None, None, None, None, None, None]

  列表解析式返回的结果是列表,列表的内容是表达式执行的结果。接着看例子:


In[13]: [x for x in range(10) if x % 2 == 0]
Out[13]: [0, 2, 4, 6, 8]

# 上面的语句等效于
ret = []
for x in range(10):
    if x % 2 == 0:
        ret.append(x)

  可以使用python的timeit来测试两种方式的执行效率。会发现列表解析的执行效率会好一些,优势显而易见。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created by Xi on 2019-02-21

import timeit
list =[]
def  fun():
    for i in range(100):
        if i%2==0:
         list.append(i)

n =1000000
if __name__ == '__main__':
    print(timeit.timeit(stmt=fun,number=n))
    print(timeit.timeit(stmt="[x for x in range(100) if x%2==0]",number=n))

输出结果:

7.920102399999999
4.7217728999999995

如果列表解析式中有if关键字呢:


[expression for item in iterable if condition]   #[表达式 for 元素 in 可迭代对象 if 条件语句]
# 等价于 
ret = []
for item in iterable:
    if condition:
        ret.append(exper)

以上介绍的只带了一个if关键字,如果有多个if关键字呢:


[experessi on for item in iterable if condition1 if condition2]
# 等价于
ret = []
for item in iterable:
    if condition1:
        if condition2:
            ret.append(experession)

针对上面来个例子:


[x for x in range(10) if x % 2 == 0 if x > 1]
[2, 4, 6, 8]

# 再来个例子
lst = [[0, 1], [1, 2], [2, 3], [3, 4], [4]]
[x for x in lst if len(x) > 1 and x.pop(0) % 2 == 0]

不但可以有多个if关键字,还可以有多个for关键字:


>>> [(x, y) for x in range(3) for y in range(3)]
[(0, 0), (0, 1), (0, 2),1(, 0), (1, 1), (1, 2),(2, 0), (2, 1), (2, 2)]

  写成一个公式类的写法为:


[expr for item1 in iterable1 for item2 in iterable2]

# 等价于
ret = []
for item1 in iterable1:
    for item2 in iterable2:
        ret.append(expr)

那么for与if都有呢?多个for语句相当于逐层for嵌套。


# 逐层嵌套
In[11]: [(x, y) for x in range(5) for y in range(5) if (x+y) % 2 == 0]
Out[11]: [(0, 0), (0, 2), (0, 4), (1, 1), (1, 3), (2, 0), (2, 2), (2, 4), (3, 1), (3, 3), (4, 0), (4, 2), (4, 4)]

[(x, y) for x in range(10) if x % 2 == 0 for y in range(10)]
# 等价于
ret = []
for x in range(10):
    if x % 2 == 0:
        for y in range(10):
            ret.append((x, y))

如果for关键字不在第一个位置,会不会出问题呢?

In[12]: [x if True for x in range(10)]
  File "<ipython-input-12-c9daacf14b27>", line 1
    [x if True for x in range(10)]
                 ^
SyntaxError: invalid syntax

因此,for关键字要写在前面,后面可以用for或if进行嵌套。

多看几个例子吧:

In[9]: [(x+1, x+2) for x in range(5)]
Out[9]: [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]

In[10]: [{x+1:x+2} for x in range(5)]
Out[10]: [{1: 2}, {2: 3}, {3: 4}, {4: 5}, {5: 6}]

列表解析用于可迭代对象做过滤和转换,返回值是列表。

help(filter)

filter(lambda x: x % 2 == 0, range(10))

list(filter(lambda x: x % 2 == 0, range(10)))

help(map)
list(map(lambda x: x+1, range(10)))

[x+1 for x in range(10)]

# Python里,可以不用filter及map函数,使用列表解析式可以秒杀filter及map
# 上面的话并不是绝对的,当数据比较大时,使用filter及map将会比列表解析式快

  在Python中,lambda的语法是唯一的。其形式如下:

lambda argument_list: expression
其中,lambda是Python预留的关键字,argument_list和expression由用户自定义。这里的argument_list是参数列表。它的结构与Python中函数(function)的参数列表是一样的。
例如:
lambda x, y: x*y;     #函数输入是x和y,输出是它们的积x*y
lambda:None;         #函数没有输入参数,输出是None
lambda *args: sum(args);  #输入是任意个数的参数,输出是它们的和(隐性要求是输入参数必须能够进行加法运算)
lambda **kwargs: 1;    #输入是任意键值对参数,输出是1

再来看一个例子,偶数求平方,奇数求立方。

lst = list(range(10))
[x ** 2 if x % 2 == 0 else x ** 3 for x in lst]
#+RESULTS:
| 0 | 1 | 4 | 27 | 16 | 125 | 36 | 343 | 64 | 729 |

总结上述代码:

x if condition else y        #当条件满足时返回x,当条件不满足时返回y。

三、字典解析

  字典解析也需要一个大括号,并且要有两个表达式:一个生成key,一个生成value;两个表达式之间使用冒号分隔,返回结果是字典。示例:

print({str(x):x for x in range(10)})
{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

看一个例子:


{str(x):y for x in range(3) for y in range(4)} # 取决于短的那个
{'0': 3, '1': 3, '2': 3}
#等价于
ret = {}
for x in range(3):
    for y in range(4):
        ret[str(x)] = y
print(ret)

四、集合解析集合解析把列表解析的中括号变成大括号,返回集合。


In[45]: {x for x in range(10)}
Out[45]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

In[46]: set01 = {x for x in range(10)}

In[47]: set01
Out[47]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

In[48]: type(set01)
Out[48]: set

使用Markdown笔记本做的整理,跟咱们论坛的MD插件不是很兼容,格式有点混乱。兄弟们多包涵!

免费评分

参与人数 5吾爱币 +6 热心值 +5 收起 理由
yui77111 + 1 + 1 谢谢@Thanks!
niebaohua + 1 + 1 谢谢@Thanks!
lsir + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wushaominkk + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
hustlzp + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Vvvvvoid 发表于 2019-2-21 12:45
<h1 id="index1">一、解析式简单介绍</h1>

标题的id 跟 目录对上
头像被屏蔽
微叶子 发表于 2019-2-21 13:33
aozakiaoko 发表于 2019-2-21 17:28
嘚瑟挨顿揍 发表于 2019-3-14 08:15
收藏  学习
Flytom 发表于 2019-3-14 09:04
原来字典也有解析式,学写了,lz辛苦
ZHENGercheng 发表于 2019-3-14 09:05
这个不错,刚好可以用到
Flytom 发表于 2019-3-14 09:09
{str(x):y for x in range(3) for y in range(4)}   value全是3,不懂
jackspar 发表于 2019-6-12 08:28
这个不错,谢谢楼主分享~
lsir 发表于 2019-6-30 22:18
太厉害了。讲得很清楚。我一看明白了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 19:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表