前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Python之解析式您知多少?

Python之解析式您知多少?

作者头像
1846122963
发布于 2018-03-09 08:38:25
发布于 2018-03-09 08:38:25
1K00
代码可运行
举报
运行总次数:0
代码可运行

解析式 解析式 今天给大家介绍Python中的解析式。

解析式简单介绍

解析式,

  1. 列表解析 # Python2只有列表解析
  2. 生成器解析 # Python3特有
  3. 集合解析 # Python3特有
  4. 字典解析 # Python3特有

解析式的作用:

  1. 修改可迭代对象
  2. 过滤可迭代对象

zip方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
In[1]: help(zip)

Help on class zip in module builtins:

class zip(object)
|  zip(iter1 [,iter2 [...]]) --> zip object
|  
|  Return a zip object whose .__next__() method returns a tuple where
|  the i-th element comes from the i-th iterable argument.  The .__next__()
|  method continues until the shortest iterable in the argument sequence
|  is exhausted and then it raises StopIteration.

In[3]: list(zip(range(10), range(10)))
Out[3]: 
[(0, 0),
(1, 1),
(2, 2),
(3, 3),
(4, 4),
(5, 5),
(6, 6),
(7, 7),
(8, 8),
(9, 9)]

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

In[5]: list(zip(range(5), range(10), range(20)))
Out[5]: [(0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4)]

zip方法用于合并多个可迭代对象,合并后的长度等于最短的可迭代对象的长度。

每种解析式都可以翻译为for循环。为什么没有元组解析?

列表解析

列表解析式示例

列表解析的一般形式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[expression for item in iterable]

接下来看几个示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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]

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)
# 可以使用ipython的timeit来测试两种方式的执行效率。
# 列表解析的执行效率会好一些

列表解析式中带有if关键字

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[exper for item in iterable if cond]
# 等价于
ret = []
for item in iterable:
    if cond:
        ret.append(exper)

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[exper for item in iterable if cond1 if cond2]
# 等价于
ret = []
for item in iterable:
    if cond1:
        if cond2:
            ret.append(exper)

针对上面来个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[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关键字:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> [(x, y) for x in range(5) for y in range(5)]
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)]

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[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嵌套。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 逐层嵌套
In[11]: [(x, y) for x in range(10) for y in range(10) if (x+y) % 2 == 0]
Out[11]: 
[(0, 0),
 (0, 2),
 (0, 4),
 (0, 6),
 (0, 8),
 (1, 1),
 (1, 3),
 (1, 5),
 (1, 7),
 (1, 9),
 (2, 0),
 (2, 2),
 (2, 4),
 (2, 6),
 (2, 8),
 (3, 1),
 (3, 3),
 (3, 5),
 (3, 7),
 (3, 9),
 (4, 0),
 (4, 2),
 (4, 4),
 (4, 6),
 (4, 8),
 (5, 1),
 (5, 3),
 (5, 5),
 (5, 7),
 (5, 9),
 (6, 0),
 (6, 2),
 (6, 4),
 (6, 6),
 (6, 8),
 (7, 1),
 (7, 3),
 (7, 5),
 (7, 7),
 (7, 9),
 (8, 0),
 (8, 2),
 (8, 4),
 (8, 6),
 (8, 8),
 (9, 1),
 (9, 3),
 (9, 5),
 (9, 7),
 (9, 9)]

[(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关键字要写在前面,后面可以用forif进行嵌套

多看几个例子吧:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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}]

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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将会比列表解析式快

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 |

总结上述代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
x if cond else y
当条件满足时返回x,当条件不满足时返回y。

列表解析的一个例子

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env python
# coding: utf-8

import time

is_forloop = input('0 is list comprehension, 1 is for loop: ')

min_time = 1000
avg_time = 0.0
run_loops = 1000

for num in range(run_loops):
    start_clock = time.clock()
    if is_forloop:
    a = []
    for x in range(0, 100):
        for y in range(0, 100):
        if x * y > 25:
            a.append((x, y))
    else:
    a = [(x, y) for x in range(100) for y in range(100) if x * y > 25]

    end_clock = time.clock()
    avg_time += end_clock - start_clock
    if (end_clock - start_clock) < min_time:
    min_time = end_clock - start_clock

print "length of result is", len(a)
print run_loops, u"次的最好运行时间为", min_time, 's'
print run_loops, u"次的平均运行时间为", avg_time / run_loops, 's'

列表解析式总结

  1. 使用列表解析式为了让代码更简洁

字典解析

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
In[14]: {str(x):x for x in range(10)}
Out[14]: 
{'0': 0,
 '1': 1,
 '2': 2,
 '3': 3,
 '4': 4,
 '5': 5,
 '6': 6,
 '7': 7,
 '8': 8,
 '9': 9}

看一个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{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)

集合解析

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

本文总结

今天给大家介绍了几种解析式,分别是:

  1. 列表解析式
  2. 字典解析式
  3. 集合解析式

在前进的路上我们并不孤单,每天都进步一点点,加油!小白甘愿做个知识的搬运工为大家服务。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-09-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小白的技术客栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
jvm内存结构
jvm主要分,堆、方法区、java栈、本地方法栈、程序计数器五个区域,其中方法区和堆区是线程共享的
leobhao
2022/06/28
8860
jvm内存结构
Java JVM 内存泄露 基本概念 解析及排查处理办法
JAVA是垃圾回收语言的一种,开发者无需特意管理内存分配。但是JAVA中还是存在着许多内存泄露的可能性,如果不好好处理内存泄露,会导致APP内存单元无法释放被浪费掉,最终导致内存全部占据堆栈(heap)挤爆进而程序崩溃。
大鹅
2021/06/16
1.2K0
助力金三银四面试JVM 高频面试题篇
方法区和堆是所有线程共享的内存区域;而java栈、本地方法栈和程序计数器是运行时线程私有的内存区域。
没有故事的陈师傅
2023/05/01
2940
助力金三银四面试JVM 高频面试题篇
jvm触发full gc条件(Linux内存管理机制)
GC,即就是Java垃圾回收机制。目前主流的JVM(HotSpot)采用的是分代收集算法。作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露和溢出的问题。与C++不同的是,Java采用的是类似于树形结构的可达性分析法来判断对象是否还存在引用。即:从gcroot开始,把所有可以搜索得到的对象标记为存活对象。缺点就是:1. 有可能不知不觉浪费了很多内存。2. JVM花费过多时间来进行内存回收。3. 内存泄露
全栈程序员站长
2022/07/28
2.7K0
jvm触发full gc条件(Linux内存管理机制)
JVM学习记录-对象已死吗
前言 先来回顾一下,在jvm运行时数据区,分为两部分,一个部分是线程共享区,主要包括堆和方法区,另一部是线程私有区分包括本地方法栈,虚拟机栈和程序计数器。在线程私有部分的三个区域是随着线程生和灭的。栈中的栈帧随着方法的进入和退出而执行着出栈和入栈操作。每一个栈帧所用内存大小在类结构确定下来时就已知了。因此这线程私有区的内存分配和回收都具备确定性,简单概括的说:这部分内存在类加载时分配,在线程结束时回收。(个人理解) 而线程共享区(堆和方法区)则不一样,一个方法中的多个分支需要的内存可能不一样,只有在程序处于
纪莫
2018/04/24
7360
JVM学习记录-对象已死吗
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM(Java Virtual Machine,即java虚拟机),java程序的运行环境(java二进制字节码的运行环境)。
寻求出路的程序媛
2024/08/01
1440
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM-方法区
方法区概述 《Java虚拟机规范》中明确说明:"尽管所有额方法区在逻辑上是属于堆的一部分,但一些简单的实现可能不会去进行垃圾收集或者进行压缩",但是对于HotspotJVM而言,方法区还有一个别名叫做Non-Heap(非堆),目的就是要和堆区分开,所以,方法区看做是一个独立于Java堆的内存空间
是小张啊喂
2023/02/21
3460
Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三)
今天介绍一下JVM内部的一些区域,以及具体的区域在运行过程中会发生哪些异内存常! 其实也就对应了内存管理的第一篇中 JVM的第三个阶段,程序运行内存溢出。
凯哥Java
2022/12/15
1.7K0
Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三)
JVM内存模型
JVM定义了若干个程序执行期间使用的数据区域。这个区域里的一些数据在JVM启动的时候创建,在JVM退出的时候销毁。而其他的数据依赖于每一个线程,在线程创建时创建,在线程退出时销毁
黑洞代码
2021/01/14
5510
JVM内存模型
JVM活学活用——GC算法 垃圾收集器
概述 ----  垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了。 jvm 中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于 java 堆和方法区中,在程序运行期间,这部分内存的分配和使用都是动态的。 对象存活判断 ----  判断对象是否存活一般有两种方式: 引用计数:每个对象有一个引用计数属
Janti
2018/04/10
6490
JVM活学活用——GC算法 垃圾收集器
JVM全网最全面试题
线程私有的,作为当前线程的行号指示器,用于记录当前虚拟机正在执行的线程指令地址。程序计数器主要有两个作用:
爱撒谎的男孩
2023/08/26
2250
JVM全网最全面试题
JVM架构和GC垃圾回收机制(JVM面试不用愁)[通俗易懂]
JVM全称是Java Virtual Machine(Java虚拟机),Java虚拟机是一种程序虚拟机(相对操作系统虚拟机),Java的运行环境实现跨平台。
全栈程序员站长
2022/08/11
4090
JVM架构和GC垃圾回收机制(JVM面试不用愁)[通俗易懂]
JVM之内存结构
定义:记住下一条执行执行的地址,一条指令执行完成后,解释器会到程序计数器找到下一条指令的地址,通过寄存器实现(cpu中最快的) 特点:线程私有,每个程序有自己的程序计数器 唯一不会存在内存溢出的地方 局部变量在栈
一只
2023/08/10
1900
GC及JVM参数
这个GC跟JVM内容太多了,理论性东西多些,少年时还能记个八九成,好久没弄,都忘记了。这次权当整理温习,再看看《深入理解JVM虚拟机》,找些过去写的博客挖点东西过来!
码农戏码
2021/03/23
9960
JVM基础和调优[通俗易懂]
注意:还是会造成线程等待现象–>Stop-The-World(STW),但是减少垃圾回收的停顿时间就会同时减小系统的吞吐量
全栈程序员站长
2022/06/28
4700
JVM基础和调优[通俗易懂]
关于JVM内存溢出的原因分析及解决方案探讨
当程序需要申请内存的时候,由于没有足够的内存,此时就会抛出OutOfMemoryError,这就是内存溢出。
技术zhai
2019/08/18
2.2K0
面试题:请讲讲JVM的内存模型
  本文内容是基于 JDK 1.6 的,不同版本虚拟机之间也许会有些许差异,但不影响我们对JVM 内存模型的整体把握和了解。
用户1263954
2019/07/16
1.3K1
面试题:请讲讲JVM的内存模型
不好意思!耽误你的十分钟,JVM内存布局还给你
在2006年加州旧金山的JavaOne大会上,一个由顶级Java开发者组成的周年性研讨会,Sun Microsystems公司突然宣布将开放Java的源代码。于是,下一年顶级项目OpenJDK诞生。
JavaSouth南哥
2024/08/20
1521
不好意思!耽误你的十分钟,JVM内存布局还给你
一篇文章彻底搞懂Java虚拟机垃圾回收(GC)机制
方法区(Method Area):有点像以前常说的“进程代码段”,这里面存放了每个加载类的反射信息、类函数的代码、编译时常量等信息
你好戴先生
2020/09/03
1.9K0
Java常见问题分析(内存溢出、内存泄露、线程阻塞等)
例:Object.finallize()、 Windows.dispose()、 System.gc()
马士兵的朋友圈
2020/09/08
1.4K0
Java常见问题分析(内存溢出、内存泄露、线程阻塞等)
推荐阅读
相关推荐
jvm内存结构
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文