鱼C论坛

 找回密码
 立即注册
查看: 1998|回复: 10

[技术交流] 实用干货:一些Python的惯用法和小技巧

[复制链接]
发表于 2017-3-29 19:43:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 新手·ing 于 2017-3-29 19:46 编辑

Pythonic其实是个模糊的含义,没有确定的解释。网上也没有过多关于Pythonic的说明,我个人的理解是更加Python,更符合Python的行为习惯。本文主要是说明一些Python的惯用法和小技巧,其实与上一篇《编码规范》有异曲同工之妙,都是为了增加代码可读性,但Pythonic可能还会从性能的角度进行考虑。

首先是两个不得不说的Python的特性List Comprehension和Generator Expression,非常精简的语法,很大程度上取代了冗长for循环。

1. 列表解析(List Comprehension)List Comprehension是在Python2.0版本中加进入的,是一种更高效、简洁的for结构替代品,作为新手写上几个后就对它爱不释手,惊呼太好用了。

例子:将原始列表中的所有元素进行某种操作后赋值给新的列表。

如果用for循环,代码如下:

  1. oldlist = []

  2. for item in oldlist:

  3. newlist.append(func(item))
复制代码


如果使用List Comprehension,代码如下:

  1. newlist = [func(item) for item in oldlist]
复制代码


我们明显看到差别,3行变一行,代码可读性增强,而且性能也提升很多,据说基本可以达到C语言的速度。

List Comprehension还支持过滤功能,在列表生成过程中套用for if字句,非常好用。示例如下:

  1. evens = [even for even in range(10) if even % 2 == 0]
复制代码


只需要一行,就将得到0到9的数字中的所有偶数,过滤掉了奇数。

2. 生成器表达式(Generator Expression):Python2.4中引入了Generator Expression。它功能上类似于List Comprehension,这你就要问了,为什么要加入这个呢。因为Generator Expression更加高效,避免了生成整个列表,改善性能及内存占用,取而代之的是返回一个generator object,通过它迭代的返回列表中的每一个值。

而且Generator Expression的使用方法也很简单,就是将List Comprehension中的中括号[]改成小括号(),示例如下:

  1. newlist = (func(item) for item in oldlist)
复制代码


这个返回的newlist其实并不是一个list,而是前面提到的generator object,可以理解为列表的一个迭代器,类似于C++中的iter。 可以通过newlist.next()迭代获得列表中的每一项。

List Comprehension和Generator Expression实在是Python中的亮点,简洁高效,一定要经常用、时时用、秒秒用。

然后是一些小技巧(大多数是很多语言都提倡的编程实践):

1. 字符串拼接:使用’’.join进行字符串拼接,而不是a += b这种形式。因为join将保证这个过程的时间复杂度为线性的,效率更高。道理很多人都知道,但是大多数人还是喜欢用“+”,因为这个实在太简洁了。其实很多语言都提供了拼接字符串的方法或者相应的类,良好编程习惯从拼接字符串开始。

2. 异常类型:基于类的异常总是好过基于字符串的异常。我们最好构造一个基于Exception的子类。

当抛出一个异常的时候,使用”raise ValueError(‘message’)”替代”raise ValueError, ’message’”的形式。

3. None判断:判断一个实例变量是否为空的时候,应该总是用’is’或者’is not’,而不要使用相等操作符。

4. 对象类型判断:对象类型的比较应该始终用isinstance()代替直接比较类型。例如:

使用if isinstance(obj, int): 而不是 if type(obj) is type(1):

5. 字符串前后缀判断:在检查前缀或后缀时避免对字符串进行切片。用startswith()和endswith()代替,因为它们是明确的并且错误更少。例如:

使用if foo.startswith('bar'): 替代 if foo[:3] == 'bar':

6. 变量值交换:在其他语言中,我们经常这样交换两个变量的值。t=a; a=b; b=t;

但是在Python中,我们还有一个简单的办法,a, b = b, a,并且这种方法更快,更酷。

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-3-29 19:47:22 | 显示全部楼层
@小甲鱼 这次板式怎么样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-29 23:14:08 | 显示全部楼层
新手·ing 发表于 2017-3-29 19:47
@小甲鱼 这次板式怎么样


可以,比之前好多了!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-29 23:31:07 | 显示全部楼层
写的很好,列表生成器的确很方便。
补充一下,列表生成器的for可以有多重,且靠右边的为内循环。
  1. >>> [str(i) + str(j) for i in 'qwe' for j in range(3)]
  2. ['q0', 'q1', 'q2', 'w0', 'w1', 'w2', 'e0', 'e1', 'e2']
复制代码

除了for if语法外,还可结合 A if <条件> else B的方式。如要生成这样的列表。
  1. [1, -4, 9, -16, 25, -36, 49, -64, 81]
复制代码

就很容易了。
  1. >>> [i * i if i % 2 != 0 else -i * i for i in range(1, 10)]
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-29 23:34:31 | 显示全部楼层
Is判断比==更严格些。
  1. >>> a = 1234
  2. >>> b = 1234
  3. >>> a == b
  4. True

  5. >>> a is b
  6. False
复制代码

只有两者的地址相同时才算is
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-30 08:57:16 | 显示全部楼层
不错的一些使用方式,既简洁又高效!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-30 16:43:31 | 显示全部楼层
感谢大家的支持!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-30 17:06:20 | 显示全部楼层
小甲鱼 发表于 2017-3-29 23:14
可以,比之前好多了!

甲鱼胸
http://bbs.fishc.com/thread-84920-1-1.html
求通过
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-31 09:45:11 | 显示全部楼层
本帖最后由 sunny霉神 于 2017-3-31 09:46 编辑
冬雪雪冬 发表于 2017-3-29 23:34
Is判断比==更严格些。

只有两者的地址相同时才算is

  1. >>> a = 23
  2. >>> b =23
  3. >>> a is b
  4. True
  5. >>> a == b
  6. True
  7. >>>
复制代码


这是咋回事啊?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-31 09:55:45 | 显示全部楼层

细究起来,可以发现python对部分整数采用固定的地址存放,这个范围为-5~256。这主要是方便的调用这些常用的数字,即使这个数字没有标签(没有赋值),也一直放在相应的地址中。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-31 17:40:55 | 显示全部楼层
冬雪雪冬 发表于 2017-3-31 09:55
细究起来,可以发现python对部分整数采用固定的地址存放,这个范围为-5~256。这主要是方便的调用这些常用 ...

哦哦,原来是这样。版主好棒!膜拜了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-30 20:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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