python可以说是近十年来增长速度最快、应用最广泛,并且是世界范围内最受欢迎的编程语言之一。今天,我来给大家讲10个我个人觉得非常实用,但是并不是所有人都知道的python编程技巧。保持这些良好的编程习惯,可以让我们写出更加清晰,更好看,更易读,更让人赏心悦目的代码了。
python语言在设计之初就有在考虑它语法的简洁性和可读性,我之前发布的一篇文章里面就有介绍过python之禅(Zen of Python),这其实是Tim Peters在python中留下的一个彩蛋。进入python然后输入import this,你会看到作者留下的一条条编程建议,如下图:
其中列下的这20条规则就是在告诉你python程序编写的指导方针。除此之外,如果大家听说过Pythonic这个词,它是用python加上后缀ic创造出的一个英语单词,它指的也是具有python独特风格、简洁而优雅的代码。最后甚至在python语言的提案中也定义了一条条让代码更加清晰、更简洁的代码规范,在这里我筛选出了10个重要的技巧,接下来我们用实列一一讲解一下吧。
在许多编程语言中,如果我们要交换变量a和b中的内容,通常我们可以定义一个临时变量,先将a的内容存放其中,然后将a设置成b,再将b设置成这个临时变量,如下图:
不过上面的这段代码在python中其实可以被改成这样的:
这样的话,程序的可读性是不是提高了很多呢。
通常在程序中我们需要组合或者拼接字符串的时候,我们可以用‘+’号来做字符串的连接。
如果只是做里两个字符串的拼接,这样写其实并没有什么问题的,但是如果字符串比较多的话,类似于这种情况:
这样的程序就是会显得非常杂乱并且不易阅读,而且在我们连接整型数据的时候,还需要类型的转换,不然程序也会报错,其实我们完全可以把程序写成下面这个样子,利用python中的‘%’语法来格式化字符串,其中‘%s’代表这里的内容会被替换成一个字符串。代码中的‘s’是string的首字母,代表字符串。‘%d’被替换成一个十进制数,‘d’是decimal的缩写,代表十进制数。最后的(...)中定义了需要被替换的内容。
format()在这里是字符串对象的一个方法,调用它会返回被格式化过后的新的字符串,而花括号中的内容会被最终替换成format()函数中转入的各个参数。使用这种的方式另一个好处就是,如果你有重复的需要被替换的内容,你可以在花括号中写入被替换参数的索引,如下图:
因此这里的这两个花括号都会被替换成同一个内容,也就是这里索引为0的第一个参数name。如果你使用的是python3.6以上的版本,这里还有一种更加简单的写法:
比如我们可以把最后的 {age} 改成 {age+1},python将会把表达式运行的结果,也就是29替换在字符串中。由于这里可以填写任意的表达式,所以你甚至可以调用一个函数返回一个数值,并替换在字符串中,这也是没有问题的。
比如在这里,我们定义了一个函数Fibonacci(),来列举斐波那契数列中的前n个数。斐波那契数列大家应该都听说过吧。简而言之就是除了最前面的两个数之外,其中每个数字都是前两个数字之和,比如0,1,1,2,3,5....5就是前面2和3的和,3就是前面1和2的和。
这个程序里面有两个变量:a和b,它们分别代表前一个数和当前的数,里面的循环会执行n次,而每次循环会先把之前的一个数存放在一个叫做nums的列表中,然后之前的数就会被替换成当前这个数,当前的这个数会被替换成前面两个数之和,然后程序会循环往复的执行下去,直到算出第n个数为止。
此时,如果我们使用print()在屏幕上显示这10个数,我们会得到下面的结果:
在这里,我们使用Fibonacci()函数来使用python中的yield语法,我们首先把“list末尾添加元素”的操作替换成yield a,然后删掉这里的nums列表
这样,修改后的程序会完成和之前一样的操作 ,这里的yield表示,每当我们计算出一个元素,就立马将这个元素给送出去,也就是说,这里外面的for loop中就会立即输出这个数。因此使用yield的好处就是,我们不需要等待整个列表都生成完毕后,再来一个一个的输出。
‘yield’ 在英文中的意思是产出;生产,单从字面上来看还是比较抽象的,不过它和 ‘return’ 的区别就是,当你的函数 yield 一个数值以后,函数并不会立马返回,而是会继续执行下去,‘yield’ 的优势在于一些非常耗时的操作。比如我们可以写一个函数来从网络上下载一系列文档,并且输出每个文档的内容,如果我们使用 ‘yield’ 则可以保证在一个文档被下载成功之后就立马输出它的内容,而且无需等待所有文档都下载完毕。
在这里我们有一系列水果的名字,存放在一个叫做fruit的列表中,如果我们希望把这些名字都改成大写,这里有很多种方法。
(1).比如写一个 ‘for loop‘ 遍历所有的名字,并把他们改写成大写
但是这里还有一个更简单的办法,之前的代码可以直接被改写成这样,后面的这个方括号语法实际上是在构造一个新的列表,并把它赋值给之前的这个fruit变量。
我们可以这样理解这个语法,方括号里的后半部分实际上是在告诉python我需要枚举fruit变量中的所有元素,而其中的每一个元素的名字叫做 ’x‘ ,而方括号里的前半部分 ’x.upper()‘ 则是将这里的每个字符串’x‘转换成大写。
(2).列表解析式其实还有另一个应用--筛选或者过滤列表中的元素
比如,如果我们希望挑选出列表里以 a 开头的水果,那么常用的一个方法就是写一个循环 ,然后挑选出需要的元素存在一个新的列表中,其实我们之前讲到的列表解析式,我们可以将程序改写成下方这样:
其中最关键的是最后面的 "if x.startwith(’a‘)",这段代码会筛选出我们需要的元素,我们可以这样理解这行代码的含义:新的列表由x构成,而x是挑选自之前的fruit列表,并且需要满足 if语句中定义的条件。
还是使用之前的列子,如果我们需要按顺序输出某个列表中的所有元素,我们可以使用 for...in 的语法。
如果我们希望同时得到每一个水果在列表中对应的索引值。比如apple的索引是0,pear是1,我们可以使用一个叫做 enumerate()的函数 ,把程序写成这样。这里的 enumerate()函数会在每一次循环的过程中提供两个参数。第一个 i 代表列表元素的索引值,第二个 x 代表列表中元素的内容。
这其实是对上一个技巧的延申,如果我们希望将fruit中的元素往前依次输出,那么应该怎么做呢?
其实我们只要在遍历元素时候加入 reversed()函数就可以了。
这里我们再重新说一下,如果我们希望输出的元素是按照水果名字的字典顺序,也就是说名字以 a a 开头的排在最前面(apple,...,zucchini),以 z 开头的排在最后,应该怎么办呢?
在这里我们能可以使用到python中的一个内建函数-sorted(),将fruit用这个函数括起来就好了,
sorted()函数会返回一个新的并经过排序后的列表。
因此我们在使用循环输出时,内容就已经被事先排序好了。
比如我们这里有两个字典,其存放不同的用户名和密码
这时候,我们可以写这么一个程序将这两个字典合并成一个字典,也就是这里的 c。
不过我们可以将这里的5行代码改成更加简洁的形式,他们都会执行完全一样的操作,这里的这连两个**号在python中叫做解包unpacking。也就是说这里的 **a和 **b相当于将字典a和b中的内容直接填写到了这里。
在python程序中,我们经常会完成这么一项操作:根据某一个条件的不同,将一个变量设置成不同的值,如下面的列子:我们会根据 score 里面存储的数值是否大于60来决定 s 里面的内容是pass 还是fail
其实这里的代码可以直接改成这样,这里的..if...else 称为python中的三元运算符。当if 后面的条件满足时,表达式会输出前面这个值;当条件不满足时,表达式会输出后面这个值。它的功能相当于C或者Java语言中的三元运算符:... ? ... : ... 尽管它们的写法完全不一样
像我们在这里,定义了一个变量name,里面存储了张三同学的姓和名,如果我们想单独提取出它的姓和名,并把他们放在不同的变量里,我们就可以利用字符串对象的 split()方法
在python中,如果我们想要读取一个文件的内容,我们可以利用open()函数打开一个文件,并利用返回的这个文件对象 f 来对这个文件进行操作。不过,当我们完成对文件的读取,不再需要这个对象之后,一定不要忘了调用 close() 方法关闭这个文件。
如果你忘记关闭这个文件,python系统将一直占用这个文件的系统资源,直到你的程序完全退出为止。对于一个小脚本来说,这不是一个大事。但是对于一个需要长时间在服务器里运行的程序,你的系统资源很快就会被吃光,接着你的程序就会崩溃,所以一个好的习惯是使用 python 的 with 语句。
将程序改写成这种形式,这样写的话就不需要手动调用 close()函数了,当 with 语句之后的代码执行完毕之后,这个文件就会自动被python关闭。
最后,大家还是要自己动手在计算机上面尝试上面讲得各种技巧 ,如果你喜欢这篇文章的话,请记得点赞加关注,欢迎大家在文章下面评论!
感谢每一位愿意读完我文章的人,创作是一件非常值得持续投入的事情,因为你们每一次的支持都是对我极大的肯定!(看我主页)