Python 容器使用的 5 个技巧和 2 个误区( 二 )

list.insert(0,item))时,它后面的所有其他成员都需要被移动,操作的时间复杂度是O(n) 。这导致在列表的头部插入成员远比在尾部追加(list.Append(item)时间复杂度为O(1))要慢 。
如果你的代码需要执行很多次这类操作,请考虑使用 collections.deque 类型来替代列表 。因为 deque 是基于双端队列实现的,无论是在头部还是尾部追加元素,时间复杂度都是 O(1)
 
3. 使用集合/字典来判断成员是否存在当你需要判断成员是否存在于某个容器时,用集合比列表更合适 。因为 itemin[...]操作的时间复杂度是O(n),而itemin{...}的时间复杂度是O(1) 。这是因为字典与集合都是基于哈希表(Hash Table)数据结构实现的 。
 

  1. # 这个例子不是特别恰当,因为当目标集合特别小时,使用集合还是列表对效率的影响微乎其微
  2. # 但这不是重点 :)
  3. VALID_NAMES = ["piglei", "raymond", "bojack", "caroline"]

  4. # 转换为集合类型专门用于成员判断
  5. VALID_NAMES_SET = set(VALID_NAMES)


  6.  
  7. def validate_name(name):
  8. if name not in VALID_NAMES_SET:
  9. # 此处使用了 Python 3.6 添加的 f-strings 特性
  10. raise ValueError(f"{name} is not a valid name!")
Hint: 强烈建议阅读 TimeComplexity - Python Wiki,了解更多关于常见容器类型的时间复杂度相关内容 。
如果你对字典的实现细节感兴趣,也强烈建议观看 Raymond Hettinger 的演讲 Modern Dictionaries(YouTube)
 
高层看容器Python 是一门“鸭子类型”语言:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子 。”所以,当我们说某个对象是什么类型时,在根本上其实指的是:这个对象满足了该类型的特定接口规范,可以被当成这个类型来使用 。而对于所有内置容器类型来说,同样如此 。
打开位于 collections 模块下的 abc(“抽象类 Abstract Base Classes”的首字母缩写)子模块,可以找到所有与容器相关的接口(抽象类)[注2]定义 。让我们分别看看那些内建容器类型都满足了什么接口:
  • 列表(list):满足IterableSequenceMutableSequence等接口
  • 元组(tuple):满足IterableSequence
  • 字典(dict):满足IterableMappingMutableMapping[注3]
  • 集合(set):满足IterableSetMutableSet[注4]
每个内置容器类型,其实就是满足了多个接口定义的组合实体 。比如所有的容器类型都满足 “可被迭代的”(Iterable) 这个接口,这意味着它们都是“可被迭代”的 。但是反过来,不是所有“可被迭代”的对象都是容器 。就像字符串虽然可以被迭代,但我们通常不会把它当做“容器”来看待 。
了解这个事实后,我们将在 Python 里重新认识面向对象编程中最重要的原则之一:面向接口而非具体实现来编程 。
让我们通过一个例子,看看如何理解 Python 里的“面向接口编程” 。
 
写扩展性更好的代码某日,我们接到一个需求:有一个列表,里面装着很多用户评论,为了在页面正常展示,需要将所有超过一定长度的评论用省略号替代 。
这个需求很好做,很快我们就写出了第一个版本的代码:
 
  1. # 注:为了加强示例代码的说明性,本文中的部分代码片段使用了Python 3.5
  2. # 版本添加的 Type Hinting 特性

  3. def add_ellipsis(comments: typing.List[str], max_length: int = 12):
  4. """如果评论列表里的内容超过 max_length,剩下的字符用省略号代替
  5. """
  6. index = 0
  7. for comment in comments:
  8. comment = comment.strip
  9. if len(comment) > max_length:
  10. comments[index] = comment[:max_length] + '...'
  11. index += 1


    推荐阅读