让代码 Pythonic.

在 Python 中打上 import this,就会出现熟悉的 The Zen of Python。

      >>> import this
      The Zen of Python, by Tim Peters

      Beautiful is better than ugly.
      Explicit is better than implicit.
      Simple is better than complex.
      Complex is better than complicated.
      Flat is better than nested.
      Sparse is better than dense.
      Readability counts.
      Special cases aren't special enough to break the rules.
      Although practicality beats purity.
      Errors should never pass silently.
      Unless explicitly silenced.
      In the face of ambiguity, refuse the temptation to guess.
      There should be one-- and preferably only one --obvious way to do it.
      Although that way may not be obvious at first unless you're Dutch.
      Now is better than never.
      Although never is often better than *right* now.
      If the implementation is hard to explain, it's a bad idea.
      If the implementation is easy to explain, it may be a good idea.
      Namespaces are one honking great idea -- let's do more of those!

突然我发现,Python 已经陪了我好久。

解决问题的时候用它;做项目的时候用它;比赛的时候也用它;即使我是以 C 入的门,有的时候也优先考虑 “用 Python 能不能做” 而不是 “用 C 能不能做” 。它以简洁干练著称,甚至流传着这样的笑话:如何把一段伪代码变成 Python 代码?——把后缀改成 .py

当然随着 Python 群体的壮大,一定的规范能够提高代码的可读性以及美观性,使其结构更加规整。这篇文章列举了一些 Pythonic 的写法,能够显得让代码更加的优雅。

这里有的参考了其他的例子,另有一些简洁写法我认为其他语言也适用,遂未列于 Pythonic 风格。

变量值交换

在 C、C++ 等语言里面,如果要交换两个变量的值,就一定会出现一个 temp 变量,作为缓存暂时存储值。而在 Python 中,有着更加直观的写法:

a, b = b, a

这样的原理是先把 a, b 做成元组,然后直接交换值,除去了中间变量 temp。

判断区间

同样的,Pythonic 就十分直观,可以将区间判断直接写成 0 < a < 1

带有索引位置的集合遍历

一般写法:

      names = ['Mike', 'Amy', 'Jhon', 'Sam']

      for i in range(len(names)):
            print (i, ': ', names[i])

Pythonic 写法:

      names = ['Mike', 'Amy', 'Jhon', 'Sam']

      for i, name in enumerate(names):
            print (i, ': ', name)

利用枚举来进行带有索引位置的集合遍历。

字符串连接

当有许多个字符串需要连在一起的时候,Python 可以这样写:

      s = ''
      for str in strs:
            s += str

当然,更 Pythonic 的写法是这样:

      s = ''.join(strs)

在使用 + 操作时,每执行一次就会在内存中生成一个新的字符串对象,造成无谓的内存浪费。而用 join 方法整个过程只会产生一个字符串对象,更加高效。

列表推导

0 到 10 的偶数列表:[ i*i for i in range(0, 10) if i% 2 == 0 ]

Unpacking

一般情况下的写法会是这样的,利用指针完成赋值:

      profile = ['Zeesain', 'Tsui', '1234']
      first_name = profile[0]
      last_name = profile[1]
      number = profile[2]

而 Pythonic 的写法会是:

      profile = ['Zeesain', 'Tsui', '1234']
      first_name, last_name, number = profile

这样的写法在原理上和交换赋值是一样的,利用元组然后 Unpack。

打开文件

一般情况下的写法是这样的:

      f = open("some_file.txt")
      try:
            data = f.read()
      ...
      finally:
            f.close()

这样的写法因为不会自动关闭文件,所以最后还是要用 finally 运行 close 函数关闭文件。下面这样写就可以自动关闭文件:

      with open("some_file.txt") as f:
            data = f.read()

尾巴

其实,我觉得一个程序员不能够被一种语言所限制,这些语法糖能够简化非常多的逻辑和代码量,但其中的原理以及算法可不能不识。当在 Golang 中不能够直接用 + 运算合并字符串的时候,我才发现 Python 用多了有的时候还真的不太好。