建议1:理解Pythonic的概念
到底什么是Pythonic,似乎每个人都有自己的看法,但是有一个公认的指南:Tim Peters的《The Zen of Python》(Python之禅)。
-
美胜丑,显胜隐,简胜杂,杂胜乱,平胜陡,疏胜密。
-
找到简单问题的一个方法,最好是唯一的方法(正确的解决之道)。
-
难以解释的实现,源自不好的主意;如有非常棒的主意,它的实现肯定易于解释
当然这些话看起来就很有玄机,似乎很有Zen的味道。所以从今天起,我们将从实际入手,分享作者张颖中的Pythonic。
![本文参照原书](https://i-blog.csdnimg.cn/blog_migrate/e7e9e454bc8d1a93d5a78bcabc307655.jpeg#pic_center)
1、Pythonic的定义
遵循Pythonic的代码,看起来就像是伪代码。以快速排序算法为例,其基本思想就是选择一个基准pivot以后将小于该值的放在左侧,大于该值放在右侧,然后对左右两侧的序列再分别按照上述过程直至子序列长度为0或1即可(想要更多了解,可以参看我的另一篇博客十大经典排序算法(动图)- 转载)。如果用python语言描述,代码如下所示:
def quicksort(array):
less = []; greater = []
if len(array) <= 1: # 截至条件
return array
pivot = array.pop()
for x in array: # 调用自身,缩小规模
if x <= pivot: less.append(x)
else: greater.append(x)
return quicksort(less)+[pivot]+quicksort(greater)
事实上,它比伪代码更加用以理解,可读性几乎超过了任意一种编程语言。
所以Pythonic也许可以定义为:充分体现Python自身特色的代码风格。
2、Python自身特色的代码风格
体现python自身特色的代码风格太多了,至今为止,几乎没有其他语言可以像python这样快速交换两个变量的值:
a, b = b, a # python 解包机制
在遍历的时候,python可以直接对值进行遍历而不要索引:
for i in alist:
do_sth_with(i)
又比如,打开文件的快速:
with open(path, 'r') as f:
do_sth_with(f)
不过我们追求的是充分利用python语法让其通俗易懂,而不是利用奇淫技巧让其他程序员暂时性懵圈,比如尽管利用切片快速实现倒序是一个不错的主意,但是它远远没有采用内置函数reverse可读性更强。
# Slice
print(alist[::-1])
# reversed
print(list(reversed(alist)))
3、标准库
如果想让你的代码可读性更强,更加Pythonic,充分了解内置标准库,尤其是内置函数和内置对象,利用字符串输出的一个例子来进行说明:
# 方法1
print('I am %s, I am %d years old' % ('Jack', 23))
# 方法2
person = {'name': 'jack', 'age': 23}
print('I am %(name)s, I am %(age)d years old' % person)
# 方法3
print('I am {name:}, I am {age} years old'.format(name='Jack', age=23))
尽管三种方法的输出是一样的,但是明显的采用format方式可读性更好,事实上其功能也更为强大,比如说快速对数字格式化(官方介绍):
# 采用科学计数法,保留两位小数,左对齐,占据10位,空位用x填充
print('{:x>+10.2e}'.format(23))
# 输出
xx2.30e+01
此外可以使用!a (应用 ascii()), !s (应用 str() )和 !r (应用 repr() )在格式化之前转换值:
"Harold's a clever {0!s}" # Calls str() on the argument first
"Bring out the holy {name!r}" # Calls repr() on the argument first
"More {!a}" # Calls ascii() on the argument first
几乎可以满足我们所有的要求,所以format或许是最为Pythonic的格式化方法。