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)数据结构实现的 。
-
# 这个例子不是特别恰当,因为当目标集合特别小时,使用集合还是列表对效率的影响微乎其微
-
# 但这不是重点 :)
-
VALID_NAMES = ["piglei", "raymond", "bojack", "caroline"]
-
# 转换为集合类型专门用于成员判断
-
VALID_NAMES_SET = set(VALID_NAMES)
-
def validate_name(name):
-
if name not in VALID_NAMES_SET:
-
# 此处使用了 Python 3.6 添加的 f-strings 特性
-
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):满足
Iterable、Sequence、MutableSequence等接口
- 元组(tuple):满足
Iterable、Sequence
- 字典(dict):满足
Iterable、Mapping、MutableMapping[注3]
- 集合(set):满足
Iterable、Set、MutableSet[注4]
“可被迭代的”(Iterable) 这个接口,这意味着它们都是“可被迭代”的 。但是反过来,不是所有“可被迭代”的对象都是容器 。就像字符串虽然可以被迭代,但我们通常不会把它当做“容器”来看待 。了解这个事实后,我们将在 Python 里重新认识面向对象编程中最重要的原则之一:面向接口而非具体实现来编程 。
让我们通过一个例子,看看如何理解 Python 里的“面向接口编程” 。
写扩展性更好的代码某日,我们接到一个需求:有一个列表,里面装着很多用户评论,为了在页面正常展示,需要将所有超过一定长度的评论用省略号替代 。
这个需求很好做,很快我们就写出了第一个版本的代码:
-
# 注:为了加强示例代码的说明性,本文中的部分代码片段使用了Python 3.5
-
# 版本添加的 Type Hinting 特性
-
def add_ellipsis(comments: typing.List[str], max_length: int = 12):
-
"""如果评论列表里的内容超过 max_length,剩下的字符用省略号代替
-
"""
-
index = 0
-
for comment in comments:
-
comment = comment.strip
-
if len(comment) > max_length:
-
comments[index] = comment[:max_length] + '...'
-
index += 1
推荐阅读
- MySQL的查询性能分析神器:explain命令的使用详解
- Python爬虫:scrapy之Cookie和Session
- Python中的高阶函数
- 国内顶尖大佬整理的Python入门教程完整版!懂中文就能学会
- 一文看懂Python变量和赋值语句
- 在Python中定义Main函数
- 红衣天使怎么养 小红衣怎么养
- 怎样正确使用阿司匹林
- 买房为什么要交公共维修基金?什么情况下使用公共维修基金……
- 医保卡使用有技巧,做对这几件事报销的更多
