Python中有用的工具(二)

一、 collections模块:更多数据结构

import collections

1. 计数器

可以使用 Counter(seq) 对序列中出现的元素个数进行统计。

例如,我们可以统计一段文本中出现的单词及其出现的次数:

>>> import collections
>>> from string import punctuation
>>> sentence = "one, two, three, one, two, three, I come from China."
>>> words_count = collections.Counter(sentence.translate(None, punctuation).lower().split())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: translate() takes exactly one argument (2 given)
>>> words_count = collections.Counter(sentence.translate(punctuation).lower().split())
>>> print(words_count)
Counter({'one,': 2, 'two,': 2, 'three,': 2, 'china.': 1, 'come': 1, 'from': 1, 'i': 1})

2. 双端队列

双端队列支持从队头队尾出入队:
>>> import collections
>>> dq = collections.deque()
>>> for i in range(10):
...     dq.append(i)
...
>>> print(dq)
deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> print(dq.pop())
9
>>> print(dq)
deque([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> for i in range(10):
...     print(dq.pop())
...
8
7
6
5
4
3
2
1
0
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
IndexError: pop from an empty deque
>>> print(dq)
deque([])
>>> for i in range(10):
...     dq.appendleft(i)
...
>>> print(dq)
deque([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
>>> for i in range(10):
...     print(dq.popleft())
...
9
8
7
6
5
4
3
2
1
0
列表 VS 双端队列

双端队列支持线程安全,在双端队列的任何一端执行添加和删除操作,它们的内存效率几乎相同(时间复杂度为O(1))。

虽然list也支持类似的操作,但是它对定长列表的操作表现很不错,而当遇到pop(0)和insert(0, v)这样既改变了列表的长度又改变其元素位置的操作时,其时间复杂度就变为O(n)了。

在双端队列中最好不使用切片和索引,你可以用popleft和appendleft方法,双端队列对这些操作做了优化。在两端的索引访问时间复杂度为O(1),但是访问中间元素的时间复杂度为O(n),速度较慢,对于快速随机的访问,还是用列表代替。

列表用于随机访问和定长数据的操作,包括切片,而双端队列适用于在两端压入或弹出元素,索引(但不包括切片)的效率可能低于列表。

class Deque:
    """模拟双端队列"""
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def addFront(self, item):
        self.items.append(item)

    def addRear(self, item):
        self.items.insert(0,item)

    def removeFront(self):
        return self.items.pop()

    def removeRear(self):
        return self.items.pop(0)

    def size(self):
        return len(self.items)

# 以下是测试代码
d = Deque()
print(d.isEmpty())
d.addRear(4)
d.addRear('dog')
d.addFront('cat')
d.addFront(True)
print(d.size())
print(d.isEmpty())
d.addRear(8.4)
print(d.removeRear())
print(d.removeFront())

#输出
True
4
False
8.4
True

3. 有序字典

字典的key按顺序排列:

import collections

items = (
    ('A', 1),
    ('B', 2),
    ('C', 3)
)

regular_dict = dict(items) # 无序输出
ordered_dict = collections.OrderedDict(items) # 有序输出

print('Regular Dict:')
for k, v in regular_dict.items():
    print(k, v)

print('Ordered Dict:')
for k, v in ordered_dict.items():
    print(k, v)

# 输出如下:
Regular Dict:
A 1
C 3
B 2
Ordered Dict:
A 1
B 2
C 3

4. 带默认值的字典

对于 Python 自带的词典 d,当 key 不存在的时候,调用 d[key] 会报错,但是 defaultdict 可以为这样的 key 提供一个指定的默认值,我们只需要在定义时提供默认值的类型即可,如果 key 不存在返回指定类型的默认值:

>>> import collections
>>> dd = collections.defaultdict(list)
>>> print(dd["foo"])
[]
>>> dd = collections.defaultdict(int)
>>> print(dd["foo"])
0
>>> dd = collections.defaultdict(float)
>>> print(dd["foo"])
0.0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值