文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
第 10 章 性能与优化
“过早地优化是万恶之源。”
——Donald Knuth,摘自Structured Programming with go to Statements
10.1 数据结构
如果使用正确的数据结构,大多数计算机问题都能以一种优雅而简单的方式解决,而Python就恰恰提供了很多可供选择的数据结构。
通常,有一种诱惑是实现自定义的数据结构,但这必然是徒劳无功、注定失败的想法。因为Python总是能够提供更好的数据结构和代码,要学会使用它们。
例如,每个人都会用字典,但你看到过多少次这样的代码:
def get_fruits(basket, fruit): # A variation is to use "if fruit in basket:" try: return basket[fruit] except KeyError: return set()
最好是使用dict结构已经提供的get方法。
def get_fruits(basket, fruit): return basket.get(fruit, set())
使用基本的Python数据结构但不熟悉它提供的所有方法并不罕见。这也同样适用于集合的使用。例如:
def has_invalid_fields(fields): for field in fields: if field not in ['foo', 'bar']: return True return False
这可以不用循环实现:
def has_invalid_fields(fields): return bool(set(fields) - set(['foo', 'bar']))
set数据结构包含许多能解决不同问题的方法,否则这些问题需要通过嵌套的for/if块才能实现。
还有许多高级的数据结构可以极大地减少代码维护负担。例如,可以看看下面的代码:
def add_animal_in_family(species, animal, family): if family not in species: species[family] = set() species[family].add(animal) species = {} add_animal_in_family(species, 'cat', 'felidea')
当然,这段代码是完全有效的,但想想看你会在你的程序中需要多少次上面代码的变种?10次?100次?
Python提供的collections.defaultdict结构可以更优雅地解决这个问题。
import collections def add_animal_in_family(species, animal, family): species[family].add(animal) species = collections.defaultdict(set) add_animal_in_family(species, 'cat', 'felidea')
每次试图从字典中访问一个不存在的元素,defaultdict都会使用作为参数传入的这个函数去构造一个新值而不是抛出KeyError。在这个例子,set函数被用来在每次需要时构造一个新的集合。
此外,collections模块提供了一些新的数据结构用来解决一些特定问题,如OrderedDict或者Counter。
在Python中找到正确的数据结构是非常重要的,因为正确的选择会节省你的时间并减少代码维护量。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论