| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Python知识库 -> Python-oneliner:列表解析和 lambda 表达式 -> 正文阅读 |
|
[Python知识库]Python-oneliner:列表解析和 lambda 表达式 |
一行 Python 可以做到什么?
简洁是 Python 的一大特点。在初学 Python 的时候,说道 Python 的简洁,最津津乐道的话题就是 “一行 Python 可以做什么”。这个话题其实涵盖相当广泛的概念,但作为一个初学者,最有冲击的自然是自己能理解的,也就是围绕
一行代码打印爱心
甚至是分形:
这些代码略有些炫技的嫌疑,但不可否认它们实现的效果确实很惊艳。不过,这些语句拆开来仔细看其实也没有什么神秘的东西,只要掌握两点:列表解析和 lambda 语句,那你也可以写出自己的“一行打印xxx”。 循环、条件语句是怎么合并到一行里的?在思考这个问题之前,先来想想为什么会有这样的需求。比如我们看第一个例子,也就是九九乘法表。按照一般的逻辑,这个表应该这样打印:
整体的结构是两层的嵌套循环,外部每迭代一次,生成一行;内部每迭代一次,生成一个算式。用 但是这里我们用了 7 行,不计最后的打印,我们生成的字符串用到了两行列表初始化,两行 列表解析的基本格式列表解析的基本语法是:
这句话将会把
几个例子最简单的,先从一个 1 ~ 10 的列表感受一下列表解析的用法:
这其实没什么特别的,要生成一个 1~10 的列表,完全不需要动用列表解析器。但假如我们要写一个平方数的列表,列表解析的价值就体现出来了:
而表达式里包含的完全可以是更复杂的东西,比如函数:
乃至是对象都可以。 另外,列表解析还支持逻辑运算。如果在插入列表的时候,我们希望这个列表只包含满足一定条件的项,这就要用到后面的
但是不满足条件的项我们希望能用另一种方法处理后也加入列表当中,换言之,列表解析能不能加入 但是如果写成这样:
Python 就会报错并且拒绝执行。 正确的做法是把
这样才能实现一个奇数算阶乘,偶数算平方的列表。 最后,列表解析是完全支持嵌套的,也就是列表解析最前面的
上面会输出三组一模一样的乘法表,这就 OK 啦! 对于打印爱心的操作,只要利用 神奇的 lambda仅仅依靠列表解析可以解决九九乘法表,但是对于 Manderbrot 集(曼德布罗特集)这种需要不断迭代来判断是否在集合内的图案,单纯的列表解析就有点乏力了。我们完全可以在外部定义一个判断每个点是否在集合内的函数,但如果就是想写在一行以内,又该怎么办呢?开头的代码出现了四次的单词 lambda 究竟是什么?
注意:上面的表达式将会返回一个函数,冒号的前后分别是这个函数的输入参数列表和返回值。我们拿最简单的索引来举个例子:
这里的
OK,下面来观察一下案例中那串老长老长的
这条只有一行的语句浓缩了 lambda 的很多技巧,有些甚至我自己也是第一次见。这句话虽然看着麻烦,但仍然值得仔细品味。 lambda 的嵌套有三个括号,看着很是头疼。我们从里到外,一个一个来看。首先,第一个括号里就出现了两个 lambda。这里就是 lambda 的嵌套,也就是在一个 lambda 表达式中引用另一个 lambda 表达式。 先看内层:
这里
可是这里多了一个
接下来那么我们看第二个括号:
这个形式就其内部参数是一个函数,也正好符合
再重复一遍几个函数的关系: lambda 实现递归在研究 众所周知,递归函数是指调用其本身的函数。但是 lambda 有个什么问题呢?对,它根本就没有名字,在定义好之前要怎么调用呢?难道要重新写一遍吗?
好像不行…… 换个思路。虽然 lambda 定义的本身是匿名的,但在 lambda 函数内部,传进的参数可是有专门的名字的哦。利用这一点,借助其它 lambda 的帮助,递归就可以实现了。 为了说明这一点,我们把
这里 现在你可能发现了,所有的函数,这样一层层嵌套,都是为了写出这个递归。 总结起来,这个结构就是:
于是,这个冗长的 lambda 所做的事情就是对范围内给定的一组 z 0 = 0 , c = 0.02 x + 0.05 j y , z k + 1 = z k 2 + c z_0=0,\quad c = 0.02x+0.05jy,\quad z_{k+1} = z_{k}^2 + c z0?=0,c=0.02x+0.05jy,zk+1?=zk2?+c 的关系迭代到
z
40
z_{40}
z40? 如果
∥
z
40
∥
<
2
\|z_{40}\|<2
∥z40?∥<2 则将该位置填充成 Mandelbrot 集的运算详情见这里。 于是,这个冗长的 lambda 所做的事情就是对给定范围内的每一组 Mandelbrot 集的定义详情见这里。 现在你也可以开始秀操作啦!现在相信你已经对列表解析和 lambda 表达式有了更深入的理解了,那么想要用一行 Python 去打印你想要的图案也不是什么困难的事情了。总结起来就是:
虽说这种过度的压缩对于代码可读往往并没有什么提升,但这其中的两个主要思想:列表解析和 lambda 表达式,却是每一个 Python 开发者都需要或多或少地了解乃至掌握的。 最后的最后,不得不提一提最经典的 one-liner,这句话熔铸了 Tim Peters 对于 Python 的情感。这就是著名的 Python 之禅(Zen of Python),第一次听说的朋友不妨试一试:
参考 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 13:57:48- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |