专栏首页Python空间Python 拓展之推导式

Python 拓展之推导式

写在之前

大家好,这里是零基础学习 Python 系列,在这里我将从最基本的Python 写起,然后再慢慢涉及到高阶以及具体应用方面。我是完全自学的 Python,所以很是明白自学对于一个人的考验,所以在这里我会尽我最大的努力,把 Python 尽可能简单的表述清楚,让更多想要学习 Python 的朋友能够入门。同时写这个教程也算是对自己之前所学知识的一个巩固和提高,喜欢的朋友们可以点个关注,有问题欢迎随时和我交流。本文所有的代码编写均是Python3 版本。

推导式是从一个或多个迭代器快速简洁的创建数据结构的一种办法,它可以将循环和条件判断结合,从而可以避免语法冗长的代码。

列表推导式

我在之前的文章中(零基础学习 Python 之 for 循环语句)写过列表推导式,但是写的相对简单,今天我准备再详细说一下,会的权当复习,不会的正好学习。

如果让你创建一个从 0 到 5 的整数列表,按照我们之前学过的方法,你可以这样:

>>> my_list = []
>>> my_list.append(0)
>>> my_list.append(1)
>>> my_list.append(2)
>>> my_list.append(3)
>>> my_list.append(4)
>>> my_list.append(5)
>>> my_list
[0, 1, 2, 3, 4, 5]

如果用我们前天学过的 for 循环,你可以这样:

>>> my_list = []
>>> for i in range(0,6):
...     my_list.append(i)
... 
>>> my_list
[0, 1, 2, 3, 4, 5]

上面的两个方法都是可行的 Python 方法,得到的都是相同的结果,但是这都不是最像 Python 风格的创建列表的方式,什么是 Python 风格?当然是简洁优雅!请看下面:

>>> my_list = [i for i in range(0,6)]
>>> my_list
[0, 1, 2, 3, 4, 5]

看完这种方法,再比较之前的那两种方法,列表推导的优点一目了然。

在第一行中,第一个变量 i 为列表的生成值,换句话说,就是将循环的结果放在列表 my_list 中,第二个 i 是循环变量,这里要提一点的是,第一个变量 i 可以是表达式,请看下面的例子:

>>> my_list = [i*i for i in range(0,6)]
>>> my_list

除了上面第一个变量可以是表达式以外,列表推导式也可以加上条件表达式,请看下面的例子:

>>> my_list = [i for i in range(0,6) if i  % 2 == 1]
>>> my_list
[1, 3, 5]

上述的例子通过列表推导式得到一个 0 到 5 之间的奇数列表,是不是要比传统的方法简洁很多呢?所以,现在你是不是该动动手指写一个传统的求奇数列表的例子来对比对比呢?

上面我们用的一直是一个 for 循环的例子,那如果是双层 for 循环呢?

>>> first = range(1,4)
>>> second = range(7,9)
>>> for i in first:
...     for j in second:
...             print(i,j)
... 
1 7
1 8
2 7
2 8
3 7
3 8

如果是上面这个例子,你该怎么用列表推导式呢?如果你思考完,请看下面的答案:

>>> first = range(1,4)
>>> second = range(7,9)
>>> results = [(i,j) for i in first for j in second]
>>> for result in results:
...     print(result)
... 
(1, 7)
(1, 8)
(2, 7)
(2, 8)
(3, 7)

我在这将上面的例子用了元组输出,具体用什么形式,看当时的情况和自己的心情。

字典推导式

除了列表,字典其实也有自己的推导式,它和列表推导式其实有些相似,也有 if 条件判断以及多个 for 循环的迭代语句,下面举个最简单的例子:

>>> words = 'rocky like python'
>>> letter_cnt = {letter:words.count(letter) for letter in words}
>>> letter_cnt
{'r': 1, 'o': 2, 'c': 1, 'k': 2, 'y': 2, ' ': 2, 'l': 1, 'i': 1, 'e': 1, 'p': 1, 't': 1, 'h': 1, 'n': 1}

上面的例子是计算句子里每个字母出现的个数,但是不知道你有没有发现,有些重复的字母的次数出现了多次?还记得怎么解决掉字符串里重复的字母么?是 set 啊,快点动手试试吧。

集合推导式

集合也不例外,也有自己的推导式,也是跟上面的列表推导式和字典推导式类似,不只是在简单的,或者是带条件判断的都是如此,请看下面的例子:

>>> my_set = {i for i in range(0,6) if i % 3 == 1}
>>> my_set
{1, 4}

生成器推导式

我们说了三个,是不是掉了什么?对,是存在感最不强的元组,那么元组推导式是什么样子的呢?你肯定想说:“简单!不就是把列表推导式的方括号变成圆括号不就得了么?!”,其实我想告诉你的事,确实有圆括号的推导式,但不是元组的,因为元组没有推导式!圆括号的那个推导式是生成器推导式,不信的话请看下面的例子:

>>> my_exp = (i for i in range(0,6))
>>> my_exp
<generator object <genexpr> at 0x110090308>
>>> type(my_exp)
<class ‘generator'>

你现在只需要知道生成器是将数据传给迭代器的一种方式就好了,至于生成器我在之后的文章中会详细讲到,尽情期待。

虽然我们还没学生成器这个概念,但是不妨碍我们学习这个推导式,你可以直接对生成器的对象进行迭代,比如像下面一样:

>>> for exp in my_exp:
...     print(exp)
... 
0
1
2
3
4
5

作为一个每个知识点都想写的人来说,这里劳烦大家再记住一点的是,一个生成器只能生成一次,如果想再生成一次的话,你会发现它消失掉了,什么意思呢,看下面的例子:

>>> second_exp = list(my_exp)
>>> second_exp
[]

现在生成器先记住这些就可以,记不住也没关系,我还会细讲生成器,我们到时候再讨论。

写在最后

最后感谢你能看到这里,希望我写的东西能够让你有到收获,但是我还是希望我在文章里插入的代码,你们能自己动手试一下,都很简单。原创不易,每一个字,每一个标点都是自己手敲的,所以希望大家能多给点支持,该关注关注,该点赞点赞,该转发转发,有什么问题欢迎在后台联系我,也可以在公众号找到我的微信加我。

本文分享自微信公众号 - Python空间(Devtogether)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-07-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Mac上用MyEclipse创建Maven Web项目

    右键 –> New –> Project –> 搜索Maven Project –> 设置存放位置 –> 选择项目类型为 maven-archetype-web...

    剑行者
  • Android开发使用Lambda表达式

    AndroidStudio从2.1开始官方通过Jack支持Java8,从而使用Lambda等特性。

    剑行者
  • Mac OS 上设置 JAVA_HOME

    由于需要,前几天在 OS X 上安装了 Oracle 的 Java 7。安装之后,发现由于我原来设置的 JAVA_HOME 为 /Library/Java/Ho...

    剑行者
  • 自己手撸一个 JSON 解析器

    JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。采用...

    好好学java
  • Android Activity的启动模式

    当通过这种模式来启动Activity时,Android总会为目标 Activity创建一个新的实例,并将该Activity添加到当前 Task栈中.注意,这种方...

    剑行者
  • Java应用在docker环境配置容器健康检查

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    程序员欣宸
  • 推荐几个IDEA插件,Java开发者撸码利器。

    一款热部署插件,只要不是修改了项目的配置文件,用它都可以实现热部署。收费的,破解比较麻烦。不过功能确实很强大。算是开发必备神器了。热部署快捷键是control+...

    好好学java
  • nanohttpd:实现跨域(CORS)请求

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    用户1148648
  • 动画+原理+代码+优化,解读十大经典排序算法

    排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见...

    好好学java
  • JVM的新生代、老年代、MinorGC、MajorGC

    原文链接:https://www.cnblogs.com/ygj0930/p/6522828.html

    微风-- 轻许--

扫码关注云+社区

领取腾讯云代金券