Python/提示与技巧
外观
< Python
在 Python 中学习许多技巧和窍门:
字符串
[编辑]- 三引号是一种使用单引号和双引号定义字符串的简单方法。
- 字符串连接“成本高昂”。使用百分比格式和 str.join() 进行连接:
(但除非您生成的字符串长度超过 500-1000 个字符,否则不必担心这一点) [1]
print "Spam" + " eggs" + " and" + " spam" # DON'T DO THIS print " ".join(["Spam","eggs","and","spam"]) # Much faster/more # common Python idiom print "%s %s %s %s" % ("Spam", "eggs", "and", "spam") # Also a pythonic way of # doing it - very fast 优化的 C 模块
[编辑]多个模块都有用 C 编写的优化版本,它们提供了几乎相同的接口,并且通常比纯 Python 实现“快得多”或更节省内存。模块行为通常在某些方面有所不同,通常是微小的,因此经常使用 C 版本。
这主要是 Python 2.x 的功能,在 Python 3 中已基本被删除,模块会自动使用优化的实现(如果有)。[2] 但是,cProfile/profile 对仍然存在(截至 Python 3.4)。
导入
[编辑]名为 module 或 Module 的模块的 C 版本称为 cModule,并且经常使用 import...as 导入以去掉前缀,如下所示:
import cPickle as pickle 为了兼容性,可以尝试导入 C 版本,如果 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– Pythonprofile增加了显著的开销,因此建议在大多数情况下使用cProfile。- (Python 3.3+ 中不需要)
cElementTree用于ElementTree,速度提高 15-20 倍,内存使用量减少 2-5 倍;[3] Python 3.3+ 中不需要,如果可能,会自动使用快速实现。
列表推导和生成器
[编辑]- 列表推导和生成器表达式对于处理小型紧凑循环非常有用。此外,它比普通的 for 循环更快。
directory = os.listdir(os.getcwd()) # Gets a list of files in the # directory the program runs from filesInDir = [item for item in directory] # Normal For Loop rules apply, you # can add "if condition" to make a # more narrow search. - 列表推导和生成器表达式可用于使用 zip 或 itertools.izip 处理两个(或更多)列表
[a - b for (a,b) in zip((1,2,3), (1,2,3))] # will return [0, 0, 0] 数据类型选择
[编辑]选择正确的数据类型对于应用程序的性能至关重要。例如,假设您有 2 个列表:
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 == None: list = [] try: # Can `seq` be iterated over? for item in seq: # If so then iterate over `seq` flatten(item, list) # and make the same check on each item. except TypeError: # If seq isn't iterable list.append(seq) # append it to the new list. 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] #returns I am Doe 参考文献
[编辑]- ↑ 'concat vs join - followup' on 'Python Rocks! and other rants 27.8.2004 Weblog of Kent S Johnson'(2004年8月27日).於2008年8月29日查閱.
- ↑ Python 3.0 中的新增功能,Guido van Rossum
- ↑ “cElementTree 模块”,2005 年 1 月 30 日,Fredrik Lundh