Python的collections模块工具

collections模块

这个模块实现了特定目标的容器,以提供Python标准内建容器 dict、list、set、tuple 的替代选择, 使用更高效

说明
Counter字典的子类,提供了可哈希对象的计数功能
defaultdict字典的子类,提供了一个工厂函数,为字典查询提供了默认值
OrderedDict字典的子类,保留了他们被添加的顺序
namedtuple创建命名元组子类的工厂函数
deque双端队列,实现了在两端快速添加(append)和弹出(pop)
ChainMap类似字典的容器类,将多个映射集合到一个视图里面

Counter类

测试demo

'''快速计数,默认增加的k的value是0
Counter对象有一个字典接口,如果引用的键没有任何记录,就返回一个0,而不是弹出一个 KeyError'''
cnt = Counter()
for word in ['red','blue','red','green']:cnt[word]+=1
cnt['a']+=1
print(cnt)
>> Counter({'red': 2, 'blue': 1, 'green': 1, 'a': 1})
'''elements()返回一个迭代器,每个元素重复计数的个数。元素顺序是任意的。如果一个元素的计数小于1, elements() 就会忽略它。'''
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> sorted(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
c = Counter()                           # a new, empty counter
c1 = Counter('gallahad')                 # a new counter from an iterable
c2 = Counter({'red': 4, 'blue': 2})      # a new counter from a mapping
c3 = Counter(cats=4, dogs=8)             # a new counter from keyword args

words = re.findall(r'\w+', open('hamlet.txt').read().lower())
print(dict(Counter(words).most_common(5))) # 排行前五
#{'asd': 92, 'asqqw': 46, 'qwdqwdqwd': 46, 'qwdqwdqdqdqd': 46, 'qwdqda': 46}

ChainMap类

合并映射字典,比update效率要高

import os, argparse

defaults = {'color': 'red', 'user': 'guest'}

parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user')
parser.add_argument('-c', '--color')
namespace = parser.parse_args()
command_line_args = {k: v for k, v in vars(namespace).items() if v is not None}

combined = ChainMap(command_line_args, os.environ, defaults)
print(combined)
print(combined['color'])
print(combined['user'])
print(combined['PWD'])
#实现内部可更新
class DeepChainMap(ChainMap):
    'Variant of ChainMap that allows direct updates to inner scopes'
    def __setitem__(self, key, value):
        for mapping in self.maps:
            if key in mapping:
                mapping[key] = value
                return
        self.maps[0][key] = value

    def __delitem__(self, key):
        for mapping in self.maps:
            if key in mapping:
                del mapping[key]
                return
        raise KeyError(key)


d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'})
d['lion'] = 'orange'
d['snake'] = 'red'
print(d)

DefaultDict

defaultdict的一个典型用法是使用其中一种内置类型(如str、int、list或dict)作为默认工厂,因为这些内置类型在没有参数调用时返回空类型。

  1. 使用str作为default_factory的例子
>>> d = collections.defaultdict(str)
>>> d
defaultdict(<class 'str'>, {})
>>> d['hello']
''
>>> d
defaultdict(<class 'str'>, {'hello': ''})
# 普通字典调用不存在的键时,将会抛异常
>>> e = {}
>>> e['hello']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'hello'
  1. 使用int作为default_factory的例子
>>> from collections import defaultdict
>>> fruit = defaultdict(int)
>>> fruit['apple'] += 2 
>>> fruit
defaultdict(<class 'int'>, {'apple': 2})
>>> fruit
defaultdict(<class 'int'>, {'apple': 2})
>>> fruit['banana']  # 没有对象时,返回0
0
>>> fruit
defaultdict(<class 'int'>, {'apple': 2, 'banana': 0})
  1. 使用list作为default_factory的例子:
>>> s = [('NC', 'Raleigh'), ('VA', 'Richmond'), ('WA', 'Seattle'), ('NC', 'Asheville')]
>>> d = collections.defaultdict(list)
>>> for k,v in s:
...      d[k].append(v)
... 
>>> d
defaultdict(<class 'list'>, {'NC': ['Raleigh', 'Asheville'], 'VA': ['Richmond'], 'WA': ['Seattle']})

OrderedDict

	collections.OrderedDict类提供了保留他们添加顺序的字典对象。
	Python字典中的键的顺序是任意的:它们不受添加的顺序的控制。

namedtuple

三种定义命名元组的方法:第一个参数是命名元组的构造器(如下的:Person,Human)

>>> from collections import namedtuple
>>> Person = namedtuple('Person', ['age', 'height', 'name'])
>>> Human = namedtuple('Human', 'age, height, name')
>>> Human2 = namedtuple('Human2', 'age height name')

实例化命令元组

>>> tom = Person(30,178,'Tom')
>>> jack = Human(20,179,'Jack')
>>> tom
Person(age=30, height=178, name='Tom')
>>> jack
Human(age=20, height=179, name='Jack')
>>> tom.age #直接通过  实例名+.+属性 来调用
30
>>> jack.name
'Jack'

deque双端队列

点击使用查看博主总结:https://blog.csdn.net/qq_17480053/article/details/51482659
列表 VS 双端队列

append(x):把元素x添加到队列的右端
appendleft(x):把元素x添加到队列的左端
clear():清空队列中所有元素
copy():创建队列的浅拷贝
count(x):计算队列中等于x元素的个数
extend(iterable):在队列右端通过添加元素扩展
extendleft(iterable):在队列左端通过添加元素扩展
index(x[, start[, stop]]):返回x元素在队列中的索引,放回第一个匹配,如果没有找到抛ValueError
insert(i, x):在队列的i索引处,插入x元素
pop():移除并返回deque右端的元素,如果没有元素抛IndexError
popleft():移除并返回deque左端的元素,如果没有元素抛IndexError
remove(value):删除第一个匹配value的元素,如果没有找到抛ValueError
reverse():在原地反转队列中的元素
rotate(n):把队列左端n个元素放到右端,如果为负值,右端到左端。如果n为1,等同d.appendleft(d.pop())
maxlen:只读属性,队列中的最大元素数

总结:

  1. 双端队列支持线程安全,在双端队列的任何一端执行添加和删除操作,它们的内存效率几乎相同(时间复杂度为O(1))。
  2. 虽然list也支持类似的操作,但是它对定长列表的操作表现很不错,而当遇到pop(0)和insert(0, v)这样既改变了列表的长度又改变其元素位置的操作时,其时间复杂度就变为O(n)了。
  3. 在双端队列中最好不使用切片和索引,你可以用popleft和appendleft方法,双端队列对这些操作做了优化。在两端的索引访问时间复杂度为O(1),但是访问中间元素的时间复杂度为O(n),速度较慢,对于快速随机的访问,还是用列表代替。
    列表用于随机访问和定长数据的操作,包括切片,而双端队列适用于在两端压入或弹出元素,索引(但不包括切片)的效率可能低于列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积极向上的Coder

一杯咖啡支持原创,技术支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值