资讯专栏INFORMATION COLUMN

Python3 CookBook | 数据结构和算法(一)

崔晓明 / 1686人阅读

摘要:提供了大量的内置数据结构,包括列表,集合以及字典。这个问题很简单,我的第一反应是循环求和,然后计算平均值,显然很麻烦。这时候就该登场了,它的作用是可以使键和值反转过来。

文章首发于知乎专栏,欢迎关注。
https://zhuanlan.zhihu.com/py...

以下测试代码全部基于 Python3。

Python 提供了大量的内置数据结构,包括列表,集合以及字典。在工作和编码中,可以说天天和它们打交道,经常碰到查询,排序和过滤等等这些问题,虽然每次解决这些问题并不困难,但总感觉代码写的很麻烦,不够优雅。

最近通过阅读《Python3 CookBook》,了解了一些更优秀的方法,做一些简单记录,与大家分享。

1、解压可迭代对象赋值给多个变量

我们都知道,一个序列是可以赋值给多个变量的,就像下面这样:

In [7]: p = (1, 2, 3)

In [8]: x, y, z = p

In [9]: x
Out[9]: 1

但如果接收的变量个数和序列元素个数不一致,就会报错,如果你不知道元素个数的话,可以采用下面这样的方式:

In [10]: x, *y = p

In [11]: y
Out[11]: [2, 3]

通过这种星号的方式,就可以解压不确定个数或任意个数的可迭代对象了,是不是很棒呢?

那么,用这个方法可以解决哪些问题呢?

先来看一种情况,现在有一个序列,去掉第一个数和最后一个数,然后求剩下数的平均值。

这个问题很简单,我的第一反应是循环求和,然后计算平均值,显然很麻烦。这时候星号表达式就派上用场了:

def drop_first_last(items):
  first, *middle, last = items
  return avg(middle)

再看一种情况,比如字符串的分割:

In [12]: line = "drwxr-xr-x  41 zyx  staff   1.4K 11 24 08:53 zyx"

In [13]: info, *fields, homedir = line.split(" ")

In [14]: info
Out[14]: "drwxr-xr-x"

In [15]: homedir
Out[15]: "zyx"
2、保留最后 N 个元素

这个问题也是经常会遇到的,比如只取文件中满足要求的前五行,或者只返回满足要求的最新十条数据。我的第一反应是列表,然后通过 push 和 pop 来操作列表来实现。

其实通过 collections.deque 可以很容易解决这个问题,使用 deque(maxlen=N) 构造函数新建一个固定大小的队列。当新元素加入并且这个队列已满时,最先进入队列的元素便会被移除,符合先进先出的原则。

In [16]: from collections import deque

In [17]: q = deque(maxlen=3)

In [18]: q.append(1)

In [19]: q.append(2)

In [20]: q.append(3)

In [21]: q
Out[21]: deque([1, 2, 3])

In [22]: q.append(4)

In [23]: q
Out[23]: deque([2, 3, 4])

如果没有设置 maxlen 则是一个无限大小的队列,可以通过 appendleft 和 pop 在队首和队尾添加删除元素。

3、字典中的键映射多个值

现在有一个需求,构建一个字典,key 是用户 ID,value 为一个列表,列表元素可以是名字,电话等等,大概是这样:

d = {"id": ["name", "phone"]}

如果我们自己构建这个字典,可能会像下面这样来实现:

d = {}
for key, value in items:
  if key not in d:
    d[key] = value
  d[key].append(value)

很麻烦,如果使用 collections 的 defaultdict 就很简单了。defaultdict 的一个特征就是它会自动初始化每个 key 刚开始对应的值,所以我们只关注添加元素操作就可以了。

优化后代码就变成了这样:

d = defaultdict(list)
for key, value in items:
  d[key].append(value)
4、字典排序

字典是无序的,但如果要控制字典中元素的顺序呢?可以使用 colletions 中的 OrderedDict,如下:

d = OrderedDict()
d["foo"] = 1
d["bar"] = 2
d["spam"] = 3
d["grok"] = 4
# Outputs "foo 1", "bar 2", "spam 3", "grok 4"

for key in d:
  print(key, d[key])

OrderedDict 内部维护这一个根据键插入顺序排序的双向链表。每次新元素插入时,便会被放在链表尾部,对于已经存在的键,并不会改变键的顺序。

但需要注意的是,OrderedDict 的大小是普通字典的两倍,所以在构建一个需要大量 OrderedDict 实例的数据结构时,就要考虑大量内存消耗的影响了。

5、字典的运算

如何取出字典中的最小值,或者对字典进行排序呢?

首先我们来看看直接使用普通的数学运算函数

In [25]: d = {"a": 11, "b": 43, "c": 3, "d": 65}

In [26]: min(d)
Out[26]: "a"

它比较的逻辑是直接比较 key,然后取出对应的 key,但如果要比较 value 呢?

In [28]: min(d.values())
Out[28]: 3

结果是正确的,但似乎并不完美,如果键值一起返回就完美了。这时候就该 zip 登场了,它的作用是可以使键和值反转过来。

In [29]: min(zip(d.values(), d.keys()))
Out[29]: (3, "c")

它直接返回了值最小的键和值,这样就很好了,不管需要哪个信息都可以直接使用。如果要对这个字典排序的话也很简单:

In [34]: sorted(zip(d.values(), d.keys()))
Out[34]: [(3, "c"), (11, "a"), (43, "b"), (65, "d")]

先写这么多吧,未完待续。。。

欢迎留言,或者添加我个人微信 zhangyx6a 交流沟通,不是微商。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/44513.html

相关文章

  • Python3 CookBook | 数据结构算法(二)

    摘要:以下测试代码全部基于查找最大或最小的个元素工作中有时会遇到这样的需求,取出数据中前面的值,或者最后的值。大家如果对堆数据结构感兴趣的话,可以继续进行深入研究,由于我了解的并不深,也没办法再展开了。 文章首发于知乎专栏,欢迎关注。https://zhuanlan.zhihu.com/py... 以下测试代码全部基于 Python3 1、查找最大或最小的 N 个元素 工作中有时会遇到这样的...

    geekidentity 评论0 收藏0
  • Python: 你不知道的 super

    摘要:整个过程还是比较清晰的,关键是要理解的工作方式,而不是想当然地认为调用了父类的方法。小结事实上,和父类没有实质性的关联。 super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: class Animal(object): def __...

    darkerXi 评论0 收藏0
  • 超实用的 Python 学习资源汇总

    摘要:链接中文翻译常用库推荐除了上面提到的之外,也是一个很好的选项。官网中文翻译如果你要编写简单的爬虫,来爬去互联网上的信息,或者调用一些外部的机遇的接口,使用这个库再也合适不过了。 作者:安龙 LeanCloud 工程师 引言 :前段时间有同学反映 Python 的学习资源汇总很少。那么学习资料哪个质量更好,效率更高?Python 有哪些非常值得学习的库?2017 年了学 2 还是学 3 ...

    宠来也 评论0 收藏0
  • Python Tips

    摘要:的三种数据类型字典列表元组,分别用花括号中括号小括号表示。约等于上句,可能是因为自定义变量名与内部函数或变量同名了。下,默认路径一般为。的日志模块中计时器定时器计划任务,。对象的问题怎样忽略警告不打印烦人的警告打印到终端同时记录到文件。 Python Enhancement Proposal。(PEP,Python增强建议书) Python之禅(import this) Pytho...

    Reducto 评论0 收藏0
  • Python每日练0006

    摘要:问题在某个集合中找到最大或最小的个元素解决方案使用模块例如此外,这两个函数都可以接受作为参数,例如输出为讨论根据官方文档对的介绍可以了解到提供了堆数据结构的实现,并且实现方式是小顶堆,也就是说每次的时候取出的是最小的元素首先使用将一个列 问题 在某个集合中找到最大或最小的N个元素 解决方案 使用heapq模块 heapq.nlargest(n, iterable, key=None)h...

    Batkid 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<