Python 中有许多可以学习的技巧和窍门:

字符串

  • 使用三重引号定义包含单引号和双引号的字符串非常方便。
  • 字符串拼接是昂贵的操作。使用百分号格式化和 str.join() 来拼接字符串: (但除非你拼接的字符串长度超过 500-1000 个字符,否则无需担心这个问题)
print("Spam" + " eggs" + " and" + " spam")  # 不要这样做
print(" ".join(["Spam", "eggs", "and", "spam"]))  # 更快/更常见的 Python 写法
print("%s %s %s %s" % ("Spam", "eggs", "and", "spam"))  # 也是 Pythonic 写法 - 非常快

优化的 C 模块

  • 许多模块有用 C 编写的优化版本,这些版本通常提供几乎相同的接口,并且比纯 Python 实现要快得多或更节省内存。模块的行为通常在某些方面有所不同,通常是微小的,因此 C 版本通常会被使用。

    这是 Python 2.x 的一个特性,在 Python 3 中已经大部分移除,但模块会自动使用优化的实现(如果可用)。然而,cProfile/profile 对仍然存在(从 Python 3.4 开始)。

  • 导入:

    • 名为 moduleModule模块的 C 版本叫做 cModule,通常通过 import ... as 来去掉前缀,如:

      import cPickle as pickle
      
    • 为了兼容性,可以尝试先导入 C 版本,如果没有找到,则回退到 Python 版本;这种情况下,使用 import ... as 是必需的,以避免代码依赖于导入的模块

      try:
          import cPickle as pickle
      except ImportError:
          import pickle
      

示例

  • 突出的例子包括:
    • (Python 2.x) cPickle 用于 pickle,速度提高 1000 倍。
    • (Python 2.x) cStringIO 用于 StringIO,在 Python 3 中被 io.StringIO 取代。
    • cProfile 用于 profile,因为 Python 的 profile 添加了显著的开销,因此推荐使用 cProfile
    • (Python 3.3+ 不再需要) cElementTree 用于 ElementTree,比纯 Python 实现快 15-20 倍,且内存使用量减少 2-5 倍;在 Python 3.3+ 中,如果可能的话,自动使用快速实现。

列表推导和生成器

  • 列表推导和生成器表达式在处理小型紧凑的循环时非常有用。而且,它们比普通的 for 循环要快。

    directory = os.listdir(os.getcwd())  # 获取程序运行目录中的文件列表
    filesInDir = [item for item in directory]  # 普通的 For 循环规则适用,你可以添加 "if 条件" 进行更精确的搜索。
    
    • 使用 zipitertools.izip 可以同时处理两个(或更多)列表:

      [a - b for (a, b) in zip((1, 2, 3), (1, 2, 3))]  # 返回 [0, 0, 0]
      

数据类型选择

  • 选择正确的数据类型对应用程序的性能至关重要。例如,假设你有两个列表:

    list1 = [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}, {'e': 5, 'f': 6}]
    list2 = [{'e': 5, 'f': 6}, {'g': 7, 'h': 8}, {'i': 9, 'j': 10}]
    
    • 你希望找到两个列表中公共的项,可以使用如下方法:

      common = []
      for entry in list1:
          if entry in list2:
              common.append(entry)
      
    • 对于较小的列表,这样的方法没问题,但对于更大的列表(例如每个列表中有成千上万的条目),以下方法会更高效:

      set1 = set([tuple(entry.items()) for entry in list1])
      set2 = set([tuple(entry.items()) for entry in list2])
      common = set1.intersection(set2)
      common = [dict(entry) for entry in common]
      
    • 使用集合操作的速度优化了查找,且比使用字符串操作来模拟集合操作要快得多。

其他技巧

  • 装饰器可以用于处理常见问题,如日志记录、数据库访问等。

  • 虽然 Python 没有内建的函数来扁平化列表,你可以使用递归函数快速完成:

    def flatten(seq, list=None):
        """flatten(seq, list=None) -> list
        Return a flat version of the iterator `seq` appended to `list`
        """
        if list is None:
            list = []
        try:
            for item in seq:
                flatten(item, list)
        except TypeError:
            list.append(seq)
        return list
    
  • 要防止 Python 脚本在独立启动后立即关闭,可以添加以下代码:

    print('Hit Enter to exit')
    raw_input()
    
  • Python 已经内建了 GUI(图形用户界面):Tkinter,基于 Tcl 的 Tk。还有其他可用的库,如 PyQt4、pygtk3 和 wxPython。

三元运算符

[on_true] if [expression] else [on_false]

x, y = 50, 25
small = x if x < y else y

布尔值作为索引:

b = 1 == 1
name = "I am %s" % ["John", "Doe"][b]  # 返回 "I am Doe"
Last modified: Friday, 31 January 2025, 1:15 AM