import collections
import re
from collections import Counter

print(collections.__all__)
"""
['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 
'UserString', 'Counter', 'OrderedDict', 'ChainMap']
这个模块实现了特定目标的容器，以提供Python标准内建容器dict , list , set , 和tuple 的替代选择。
deque: 类似列表(list)的容器，实现了在两端快速添加(append)和弹出(pop)
defaultdict: 字典的子类，提供了一个工厂函数，为字典查询提供一个默认值
namedtuple(): 创建命名元组子类的工厂函数，生成可以使用名字来访问元素内容的tuple子类
UserDict: 封装了字典对象，简化了字典子类化
UserList: 封装了列表对象，简化了列表子类化
UserString: 封装了字符串对象，简化了字符串子类化（中文版翻译有误）
Counter: 字典的子类，提供了可哈希对象的计数功能
OrderedDict: 字典的子类，保存了他们被添加的顺序，有序字典
ChainMap: 类似字典(dict)的容器类，将多个映射集合到一个视图里面
"""

text = 'remove an existing key one level down remove an existing key one level down'
# \w	匹配非特殊字符，即a-z、A-Z、0-9、_、汉字
words = re.findall(r'\w+', text)
print(Counter(words).most_common(10))

#计算列表中单词的个数
cnt = Counter()
for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
    cnt[word] += 1
print(cnt)

# #上述这样计算有点嘛，下面的方法更简单，直接计算就行
L = ['red', 'blue', 'red', 'green', 'blue', 'blue']
print(Counter(L))

# 元素从一个iterable 被计数或从其他的mapping (or counter)初始化：
# 字符串计数
print(Counter('gallahad'))

# 字典计数
print(Counter({'red': 4, 'blue': 2}))

# 是个啥玩意计数
print(Counter(cats=4, dogs=8))

"""
1、elements()
描述：返回一个迭代器，其中每个元素将重复出现计数值所指定次。 元素会按首次出现的顺序返回。 如果一个元素的计数值小于1，elements() 将会忽略它。
语法：elements( )
参数：无
"""
c = Counter(a=4, b=2, c=0, d=-2)
print(c)
print(list(c.elements()))
print(sorted(c.elements()))
c = Counter(a=4, b=2, c=0, d=5)
print(list(c.elements()))

"""
2、most_common()
返回一个列表，其中包含n个最常见的元素及出现次数，按常见程度由高到低排序。 
如果n被省略或为None，most_common() 将返回计数器中的所有元素，
计数值相等的元素按首次出现的顺序排序，经常用来计算top词频的词语。
"""
print(Counter('abracadabra').most_common(3))
print(Counter('abracadabra').most_common(5))

"""
3、subtract()
从迭代对象或映射对象减去元素。像dict.update() 但是是减去，而不是替换。输入和输出都可以是0或者负数。
"""
c = Counter(a=4, b=2, c=0, d=-2)
d = Counter(a=1, b=2, c=3, d=4)
c.subtract(d)
print(c)

#减去一个abcd
str0 = Counter('aabbccdde')
str0.subtract('abcd')
print(str0)

"""
4、字典方法
通常字典方法都可用于Counter对象，除了有两个方法工作方式与字典并不相同。
fromkeys(iterable)
这个类方法没有在Counter中实现。
update([iterable-or-mapping])
从迭代对象计数元素或者从另一个映射对象 (或计数器) 添加。 像 dict.update() 但是是加上，而不是替换。
另外，迭代对象应该是序列元素，而不是一个 (key, value) 对。
"""
c = Counter(a=4, b=2, c=0, d=-2)
print(sum(c.values()))
print(list(c))
print(set(c))
print(dict(c))
print(c.items())
print(+c)  # 删除零计数和负计数
c.clear()
print(c)
"""
5、数学操作
这个功能非常强大，提供了几个数学操作，可以结合 Counter 对象，以生产 multisets (计数器中大于0的元素）。 
加和减，结合计数器，通过加上或者减去元素的相应计数。交集和并集返回相应计数的最小或最大值。
每种操作都可以接受带符号的计数，但是输出会忽略掉结果为零或者小于零的计数。
"""
c = Counter(a=3, b=1)
d = Counter(a=1, b=2)
print(c+d)
print(c - d)
print(c & d)
print(c | d)
