对比几段代码,看看你是 Python 菜鸟仍是老鸟

Python 里有个小彩蛋:python

在 Python Shell 里输入 import this 程序员

这段话被称做“Python 之禅”(The Zen of Python),它列举了一些 Python 所推崇的理念,好比:编程

优美胜于丑陋
明确胜于隐晦
简单胜于复杂

可读性很重要
不要忽略错误
面对不肯定时, 拒绝猜想
如今作好过不作,但盲目动手不如不作
若是你的实现很难说清楚,那是个坏想法;反之亦然

当你学完基础,能够写点代码的时候,可能常常感受本身的实现很别扭。有经验的程序员会一眼看出你的代码出自一个初学者之手。这就是咱们常常说的,代码不够 pythonicapp

所谓 pythonic,我以为包含两方面:一是代码的风格符合 Python 的特色,能合理使用 Python 的“语法糖”;二是代码简洁优美,稳定性高,可读性好,便于维护和修改。所谓“Python 之禅”并不只限于 Python,不少理念是编程普适的。函数

好比来实现对一个列表中元素的遍历访问,我见过不少次有人这么写:学习

for i in range(len(lst)):
    print(lst[i])

这样的同窗极可能是以前有过 C/C++ 或 Java 的经验。这么写功能上没问题,但不够简洁,不够 pythonic。更好的实现方式:this

for i in lst:
    print(i)

这种不影响功能,但能简化程序、提升可读性的语法,咱们称之为“语法糖”(Syntactic sugar)。Python 中相似的例子还有很多,来举几个:spa

一、交换两个变量的值,普通写法:翻译

temp = a
a = b
b = temp

pythonic 写法:设计

a, b = b, a

二、相似的解包(unpacking)用法还能够实现多个返回值的函数。普通写法:

def func(a, b):
    result = [b, a]
    return result
r = func(a, b)
x = r[0]
y = r[1]

pythonic 写法:

def func(a, b):
    return b, a
x, y = func(a, b)

三、读写文件,普通写法:

f = open('filename.txt')
text = f.read()
print(text)
f.close()

pythonic 写法:

with open('filename.txt') as f:
    for line in f:
        print(line)

with 的好处是即便出错,也会帮你关闭文件。

四、拼接字符串,普通写法:

letters = ['h', 'e', 'l', 'l', 'o']
s = ''
for l in letters:
    s += l
print(s)

pythonic 写法:

print(''.join(letters))

五、关于前面遍历列表的例子,若是你想带上索引,能够这么写:

for i, elem in enumerate(lst):
    print(i, elem)

遍历字典项:

for key, value in dct.items():
    print(key, value)

六、取出列表中大于 0 的元素,生成新列表。普通写法:

new_lst = []
for i in lst:
    if i > 0:
        new_lst.append(i)

pythonic 写法:

new_lst = [i for i in lst if i > 0]

这个被称为“列表解析式”(List comprehension,中文翻译说法有不少),能够说是很是 pythonic 的一个用法了。

更进一步,若是数据量很大,而你对新列表仅仅是遍历操做,并不须要一个列表对象,能够采用生成器

new_lst = (i for i in lst if i > 0)
for i in new_lst:
    print(i)

这样会更节省资源,提高执行效率。

七、判断一个值是否为True、是否为空列表、是不是None,普通写法:

if x == True:
    pass
if len(y) == 0:
    pass
if z == None:
    pass

pythonic 写法:

if x:
    pass
if not y:
    pass
if z is None:
    pass

八、根据键名获取字典中对应的值,普通写法:

value = dct[key]

这样的问题在于,若是 key 不存在,代码就报错跳出。因而你不得不增长更多的判断。

pythonic 写法:

value = dct.get(key, 0)

改用 get 方法,不存在时会获得 None,或者指定的默认值(这里是 0)。

篇幅所限,以上仅仅是一些比较具备表明性的例子。但凡事要有度,过度追求 pythonic 的写法也可能致使代码的可读性降低。好比有人喜欢把不少功能写在一个语句中,这反倒不 pythonic 了。因此,咱们须要有一些设计的原则,但又没必要拘泥于具体的形式,不然就钻入牛角尖了。

那么对于学习者来讲,如何才能写出更 pythonic 的代码呢?说到底仍是个经验积累的过程,菜鸟不可能看本书、上个课就一晚上变成老鸟,但只要坚持得够久就能够。我这边给几个建议:

  1. 多看。看官方库、优秀项目,学习别人的代码。以及看一些优质的教程和经验分享,好比 Crossin的编程教室
  2. 多搜。当你实现一个小功能后,去网上搜一下,别人是怎么写的,对比下是否是比你本身的更好。举个例子:如何从列表中删除重复元素。你本身能够经过循环实现,但只要搜一下,就会知道 list(set(x)) 这种用法。
  3. 多写。本身还没写几行代码,就先别纠结什么效率什么风格了。最终仍是要写上足够量的代码,才会有“悟道”的那一刻。

另外,对于代码自己,Python 有一套书写规范,叫作 PEP8。里面约定了不少细节,好比哪里该空格、注释怎么写、什么地方该换行、如何命名等等。连接:https://www.python.org/dev/peps/pep-0008/,网上还有翻译好的中文版,务必找时间看一看。

最后,留2个小做业:

1. 判断 一个列表 A 是否为另外一个列表 B 的“子集”,也就是列表 A 中的元素是否都在列表 B 中。
2. 计算 1 加到 100 的和
尽量写出你认为 pythonic 的代码。


════

其余文章及回答:

学编程:如何自学Python | 新手引导 | 一图学Python

开发案例:智能防挡弹幕 | 红包提醒 | 流浪地球

欢迎搜索及关注:Crossin的编程教室

相关文章
相关标签/搜索