collections--高性能容器

本文深入探讨了Python标准库中的集合工具,包括Counter、deque、defaultdict、namedtuple和OrderedDict等高级数据结构的使用方法及应用场景,展示了如何利用这些工具进行高效的数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源代码: Lib/collections.py 和 Lib/_abcoll.py

说明
namedtuple()用于创建具有命名字段的元组子类的工厂函数
deque类似列表的容器,两端都有快速追加和弹出(列表)
Counter用于计算可哈希对象的dict子类
OrderedDict记住订单条目的dict子类已添加 (有序字典)
defaultdictdict子类调用工厂函数来提供缺失值

Counter对象

提供计数器工具以支持方便和快速的计数。

>>> form collections import Counter
>>> cnt = Counter()
>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
...     cnt[word] += 1
>>> cnt
Counter({'blue': 3, 'red': 2, 'green': 1})

>>> # 在Hamlet里面找出出现频率最高的单词(前10)
>>> import re
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
 ('you', 554),  ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]
class collections.Counter([ iterable-or-mapping ] )

Counter是 dict 用于计算可哈希对象的子类。它是一个无序集合,其中元素存储为字典键,其计数存储为字典值。计数允许为任何整数值,包括零或负计数。该Counter 类是类似于其他语言包或者多集。

初始化
>>> c = Counter()                           # a new, empty counter
>>> c = Counter('gallahad')                 # a new counter from an iterable
>>> c = Counter({'red': 4, 'blue': 2})      # a new counter from a mapping
>>> c = Counter(cats=4, dogs=8)             # a new counter from keyword args

缺少的项返回0,而不是提出KeyError:

>>> c = Counter(['eggs', 'ham'])
>>> c['bacon']      # count of a missing element is zero
0

将计数设置为零不会从计数器中删除元素。del完全删除它:

>>> c['sausage'] = 0                        # counter entry with a zero count
>>> del c['sausage']                        # del actually removes the entry

Counter对象支持所有字典的方法,除此之外h还有三种方法:
(1)elements()
返回一个迭代器,重复每个重复次数的元素。元素以任意顺序返回。如果元素的计数小于1,elements()则忽略它。

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']

(2)most_common([ n ] )
返回n个最常见元素及其计数的列表,从最常见到最少。如果省略nNone,则 most_common()返回计数器中的所有元素。具有相同计数的元素是任意排序的:

>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]

(3)subtract([ iterable-or-mapping] )
从迭代或从另一个映射 (或计数器)中减去元素。喜欢dict.update()但是减去计数而不是替换它们。输入和输出都可以为零或负数。

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> c.subtract(d)
>>> c
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
使用Counter对象的常见模式:
sum(c.values())                 # total of all counts
c.clear()                       # reset all counts
list(c)                         # list unique elements
set(c)                          # convert to a set
dict(c)                         # convert to a regular dictionary
c.items()                       # convert to a list of (elem, cnt) pairs
Counter(dict(list_of_pairs))    # convert from a list of (elem, cnt) pairs
c.most_common()[:-n-1:-1]       # n least common elements
c += Counter()                  # remove zero and negative counts
>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d                       # add two counters together:  c[x] + d[x]
Counter({'a': 4, 'b': 3})

>>> c - d                       # subtract (keeping only positive counts)
Counter({'a': 2})

>>> c & d                       # intersection:  min(c[x], d[x])
Counter({'a': 1, 'b': 1})

>>> c | d                       # union:  max(c[x], d[x])
Counter({'a': 3, 'b': 2})

deque对象

class collections.deque([ iterable [,maxlen ] ] )

返回一个从左到右(使用append())初始化的新deque对象,其中包含来自iterable的数据。如果未指定iterable,则新的deque为空。

Deque对象支持以下方法:

append(x ): 将x添加到双端队列的右侧。
appendleft(x ): 将x添加到双端队列的左侧。
clear(): 从双端队列中删除所有元素,使其长度为0。
count(x ): 计算deque中元素x的数量。
extend(iterable): 通过附加可迭代参数中的元素来扩展双端队列的右侧。
extendleft(iterable): 通过附加来自iterable的元素来扩展双端队列的左侧。注意,左边的序列会导致反转迭代参数中元素的顺序。
pop(): 从双端队列的右侧移除并返回一个元素。如果没有元素,则提出一个IndexError。
popleft(): 从双端队列的左侧移除并返回一个元素。如果没有元素,则提出一个IndexError。
remove(值): 删除第一次出现的值。如果没有找到,提出一个 ValueError。
reverse(): 在原地反转deque的元素然后返回None。
rotate(n = 1 ): 向右旋转deque n步。如果n为负数,则向左旋转。
当双端队列不为空时,向右旋转一步相当于 d.appendleft(d.pop()),向左旋转一步相当于d.append(d.popleft())。

Deque对象还提供一个只读属性:

maxlen: 一个双端队列的最大大小或None无边界。

>>> from collections import deque
>>> d = deque('ghi')                 # make a new deque with three items
>>> for elem in d:                   # iterate over the deque's elements
...     print elem.upper()
G
H
I

>>> d.append('j')                    # add a new entry to the right side
>>> d.appendleft('f')                # add a new entry to the left side
>>> d                                # show the representation of the deque
deque(['f', 'g', 'h', 'i', 'j'])

>>> d.pop()                          # return and remove the rightmost item
'j'
>>> d.popleft()                      # return and remove the leftmost item
'f'
>>> list(d)                          # list the contents of the deque
['g', 'h', 'i']
>>> d[0]                             # peek at leftmost item
'g'
>>> d[-1]                            # peek at rightmost item
'i'

>>> list(reversed(d))                # list the contents of a deque in reverse
['i', 'h', 'g']
>>> 'h' in d                         # search the deque
True
>>> d.extend('jkl')                  # add multiple elements at once
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1)                      # right rotation
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
>>> d.rotate(-1)                     # left rotation
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])

>>> deque(reversed(d))               # make a new deque in reverse order
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear()                        # empty the deque
>>> d.pop()                          # cannot pop from an empty deque
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in -toplevel-
    d.pop()
IndexError: pop from an empty deque

>>> d.extendleft('abc')              # extendleft() reverses the input order
>>> d
deque(['c', 'b', 'a'])
处理 deques 的各种方法

有界长度deques提供类似于Unix中的过滤器的功能 tail:

def tail(filename, n=10):
    'Return the last n lines of a file'
    return deque(open(filename), n)

defaultdict对象

class collections.defaultdict([ default_factory [,... ] ] )

defaultdict是内置类 dict 的子类。它会覆盖一个方法并添加一个可写实例变量。
其余功能与dict相同。

defaultdict除标准dict操作外,对象还支持以下方法:

(1)missing(key):
如果default_factory属性为None,KeyError则以键为参数引发 异常。
如果default_factory不是None,则在没有参数的情况下调用它来为给定键提供默认值,将该值插入键的字典中并返回。

defaultdict 对象支持以下实例变量:

default_factory: 该属性由__missing__()方法使用;
它从构造函数的第一个参数初始化(如果存在),或者None如果不存在则初始化 。

defaultdict示例
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

namedtuple() 具有命名字段的元组的工厂函数

collections.namedtuple(typename,field_names [,verbose = False ] [,rename = False ] )

返回名为typename的新元组子类。
新子类用于创建类似元组的对象,这些对象具有可通过属性查找访问的字段以及可索引和可​​迭代的字段。

OrderedDict对象

class collections.OrderedDict([ items ] )

返回一个dict子类的实例,支持通常的dict 方法。
OrderedDict.popitem(last = True ): popitem()有序字典的方法返回并删除(键,值)对。
如果last为真,则以LIFO(先进后出)顺序返回对,
如果为false,则以FIFO(先进先出)顺序返回。

除了通常的映射方法之外,有序字典还支持使用反向迭代reversed()。

OrderedDict 例子和食谱

由于有序字典会记住其插入顺序,因此它可以与排序结合使用,以生成排序字典:

>>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}

>>> # 按键排序
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

>>> # 按值排序
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

>>> # 按键(len(key))排序
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])

集合抽象基类

集合模块提供以下抽象基类:
详情见: 集合抽象基类

类collections.Container
类collections.Hashable
类collections.Sized
类collections.Callable
对于类的抽象基类分别提供的方法:contains(), hash(),len(),和__call__()。

类collections.Iterable: 提供__iter__()方法的类的ABC 。

类collections.Iterator: 用于提供__iter__()和 next()方法的类的ABC 。

类collections.Sequence
类collections.MutableSequence: ABCs用于只读和可变序列。

类collections.Set
类collections.MutableSet: 用于只读和可变集的ABC。

类collections.Mapping
类collections.MutableMapping: ABC用于只读和可变映射。

类collections.MappingView
类collections.ItemsView
类collections.KeysView
类collections.ValuesView: 用于映射,项目,键和值视图的 ABC 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值