当前位置 : 主页 > 编程语言 > 其它开发 >

Python 中 collections 模快

来源:互联网 收集:自由互联 发布时间:2022-05-30
目录 Collections 模快 一、 简介 二、 Counter 1、 基本用法 2、 常用函数 3、 数学运算 三、 deque 四、 OrderedDict 五、 nametuple 1、 简介 2、 构造函数 3、 常用方法 六、 defaultdict 1、 简介 2、

目录
  • Collections 模快
    • 一、 简介
    • 二、 Counter
      • 1、 基本用法
      • 2、 常用函数
      • 3、 数学运算
    • 三、 deque
    • 四、 OrderedDict
    • 五、 nametuple
      • 1、 简介
      • 2、 构造函数
      • 3、 常用方法
    • 六、 defaultdict
      • 1、 简介
      • 2、 构造函数
      • 3、 default_factory
        • 3.1 list
        • 3.2 int
        • 3.3 set
        • 3.4 自定义对象
    • 七、 ChainMap
      • 1、 简介
      • 2、 常用方法
    • 八、 UserDict
    • 九、 UserList
    • 十、 UserString

Collections 模快 一、 简介

collections模块实现了特定目标的容器,以提供Python标准内建容器dict ,list , set , 和tuple的替代选择

通俗来说,Python内置的数据类型和方法,collections模块在这些内置类型的基础提供了额外的高性能数据类型,比如基础的字典是不支持顺序的,collections模块的OrderedDict类构建的字典可以支持顺序,collections模块的这些扩展的类用处非常大,熟练掌握该模块,可以大大简化Python代码

官方文档:【https://docs.python.org/zh-cn/3/library/collections.html】

所有子类

名称 功能 namedtuple() 创建命名元组子类的工厂函数 deque 类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop) ChainMap 类似字典(dict)的容器类,将多个映射集合到一个视图里面 Counter 字典的子类,提供了可哈希对象的计数功能 OrderedDict 字典的子类,保存了他们被添加的顺序 defaultdict 字典的子类,提供了一个工厂函数,为字典查询提供一个默认值 UserDict 封装了字典对象,简化了字典子类化 UserList 封装了列表对象,简化了列表子类化 UserString 封装了字符串对象,简化了字符串子类化
import collections
print(collections.__all__)  # 查看对象中的所有子类
二、 Counter 1、 基本用法

一个计数器工具提供快速和方便的计数,Counter是一个dict的子类,用于计数可哈希对象。它是一个集合,元素像字典键(key)一样存储,它们的计数存储为值。计数可以是任何整数值,包括0和负数,Counter类有点像其他语言中的bags或multisets。简单说,就是对可迭代对象的里面每个元素的计数

lis = ["blue", "blue", "blue", "red", "red", "green", "green", "blue", "red", "red"]
# 传统方法计数
count_lis = {}
for i in lis:
    if count_lis.get(i, -1) == -1:
        # 说明获取值失败,没有存入值
        count_lis[i] = 1
        continue
    count_lis[i] += 1
print(count_lis)

# 使用Counter计数
from collections import Counter
count = Counter(lis)  # 参数是可迭代对象
print(dict(count))  

# 也可以是
coun = Counter(a=4, c=5)  # 表示有4个a,5个c
print(coun)

Counter创建对象的时候,可以传入字符串,可迭代对象,Counter对象,或mapping映射等

2、 常用函数 函数 作用 del count[key] 删除指定键key count.elements() 返回一个迭代器 most_common(n) 返回一个列表,其中包含 n 个最常见的元素及出现次数 subtract(iterable or mapping) 从迭代对象或映射对象减去元素。但是是减去,而不是替换 update(iterable or mapping) 从迭代对象或映射对象添加元素 clean() 清空里面的内容 get(key) 得到对应键的值 items() 得到对象内所有的键值对

在相等性检测中,不存在的元素会被当作计数值为零

同时,字典里面的方法也可以在这里面使用

from collections import Counter
lis = ["blue", "blue", "blue", "red", "red", "green", "green", "blue", "red", "red"]
count = Counter(lis)  # 参数是可迭代对象
count.update(["r", "s", "r"])  # 向里面添加元素
del(count["r"])  # 删除键"r"
print(count.elements())  # 返回可迭代对象
print(count.most_common(3))  # 只输出前三个数量最多的元素
count.subtract(["z", "r", "r"])  # 减去里面的元素,注意,不是删除
print(count.items())  # 得到键值对
count.clear()  # 清空内容
3、 数学运算

加和减,结合计数器,通过加上或者减去元素的相应计数。交集和并集返回相应计数的最小或最大值。每种操作都可以接受带符号的计数,但是输出会忽略掉结果为零或者小于零的计数

from collections import Counter
count = Counter(a=3, b=-4)  # 参数是可迭代对象
c_div = Counter(a=1, b=2, c=3)  # 创建一个新的对象

print(count)
# 进行数学操作,如果c_div有count里面的键,则进行相应的数学运算
print(count - c_div)
print(count + c_div)

# 单目数学运算
print(+count)  # 只取值为正数的键
print(-count)  # 对负数取反,并且正数忽略

# 进行逻辑运算
print(count & c_div)  # 交集运算
print(count | c_div)  # 并集运算

# 比较运算
print(count == c_div)  # 其为判断每一个键值对是否相同
三、 deque

双端队列,可以快速的从另外一侧追加和推出对象,deque是一个双向链表,针对list连续的数据结构插入和删除进行优化。它提供了两端都可以操作的序列,这表示在序列的前后你都可以执行添加或删除操作。双向队列(deque)对象支持以下方法:

方法 作用 append(x) 添加元素到右端 appendleft(x) 添加元素到左端 clear() 清空所有的元素 copy() 浅拷贝 count(x) 计算值为x出现的次数 extend(iterable) 拓展队列的右侧 extendleft(iterable) 拓展队列的左侧,反顺序添加 index(x[, start[, end]]) 返回元素 x 的索引 insert(i, x)x 位置插入元素 i pop() 删除最右边的元素并返回该元素 popleft() 删除最左边的元素并返回该元素 remove(val) 移除队列中的第一个 val 元素 reverse() 逆序排列 rotate(n) 向右循环移动 n 步。 如果 n 是负数,就向左循环 maxlen 返回队列的最大长度

如果deque不是空的,向右循环移动一步就等价于 d.appendleft(d.pop()) , 向左循环一步就等价于 d.append(d.popleft())

同时,列表可以使用的方法,在队列中都可以使用

四、 OrderedDict

有序词典就像常规词典一样,但有一些与排序操作相关的额外功能,popitem() 方法有不同的签名。它接受一个可选参数来指定弹出哪个元素。move_to_end() 方法,可以有效地将元素移动到任一端

与dict字典的不同之处:

  • 常规的dict被设计为非常擅长映射操作,跟踪插入顺序是次要的
  • OrderedDict旨在擅长重新排序操作。空间效率、迭代速度和更新操作的性能是次要的
  • 算法上,OrderedDict可以比dict更好地处理频繁的重新排序。这使其适用于跟踪最近的访问
  • 对于OrderedDict,相等操作检查匹配顺序
  • OrderedDict类的popitem()方法有不同的签名。它接收一个可选参数来指定弹出哪个元素
  • OrderedDict类有一个move_to_end()方法,可以有效地将元素移动到任意一端
  • Python 3.8之前,dict缺少__reversed__()方法

OrderedDict特殊功能

方法 作用 popitem(last=True) 将对象中的元素从一侧移除,并返回移除的键值对 move_to_end(key, last=True) 将现有键移动到有序字典的任一端 reversed(OrderedDict) 有序字典提供了逆序迭代的支持

参数:

  • last:是否从最后一个元素开始进行操作,默认为True
  • key:将现有的键移动到有序字典的任意端,last=True时,从现有的键移动到右端
五、 nametuple 1、 简介

生成可以使用名字来访问元素内容的tuple子类,命名元组赋予每个位置一个含义,提供可读性和自文档性。它们可以用于任何普通元组,并添加了通过名字获取值的能力,通过索引值也是可以的

2、 构造函数
namedtuple(typename,field_names,*, rename=False, default=None, module=None)

参数:

  • typename:该参数指定所创建的tuple子类类名,相当于用户定义了一个新类
  • field_names:该参数是一个字符串序列,可以是["x", "y"] 或 "x y" 或 "x, y"等,其可以为存字符串,有空白或逗号分隔开元素名。任何有效的标识符都可以作为字段名
  • rename:如果rename为真,无效字段名会自动转换成位置名,如["x", "1", "def", "abc", "x"] -> ["x", "_1", "_2", "abc", "_4"]消除不合法的标识符和重复字段
  • default: 可以为 None 或者是一个默认值的iterable。如果一个默认值域必须跟其他没有默认值的域在一起出现,defaults 就应用到最右边的参数。比如如果域名 ['x', 'y', 'z'] 和默认值 (1, 2) ,那么 x 就必须指定一个参数值 ,y 默认值 1z 默认值 2
  • module:如果设置了该参数,那么该类位于该模快下,因此该自定义类的__module__属性将被设为该参数值
3、 常用方法

为了防止字段冲突,方法和属性以下划线开始

方法 作用 _make(iterable) 类方法从存在的序列或迭代实例中创建一个新实例 _asdict() 返回一个新的dict,它将字段名称映射到它们对应的值 _replace(**kwargs) 返回一个新的命名元组实例,并将指定域替换为新的值 _fields 字符串元组列出了字段名,用于提醒和从现有元组创建一个新的命名元组类型 _field_defaults 字典将字段名映射到默认值 getattr() 获取对应元素的属性值

同时也可以使用字典的拆包来命名元组

from collections import namedtuple
tup = namedtuple('tup', ['a', 'b', 'v'], rename=True, defaults=[8, 9, 10])  # 创建对象
print(tup._field_defaults)  # 给字段名设置defaults里面的默认值
tup = tup(0, 1, 2)  # 给里面的字段名赋值
print(getattr(tup, "a"), tup.a)  # 获取属性值
print(tup._fields)  # 获取字段名

命名元组等于是将每一个元素都添加了一个名称,而不是索引

六、 defaultdict 1、 简介

在普通的字典中,获取一个key有两种方法,第一个使用get(key),第二种是通过索引来获取值

当使用索引来获取键值对时,如果应用的key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict

2、 构造函数
defaultdict(default_factory=None, /[, ...])

返回一个新的类似字典的对象。defaultdict是内置dict类的子类。它重载了一个方法并添加可写的实例变量。其余功能与dict类相同

default_factory:第一个参数用于为该属性提供初始值,默认为None。所有其他参数(包括关键字参数)都相当于传递给dict的构造函数,还支持一下方法作为扩展:__missing__(key)

  • 如果default_factory属性为None,则调用本方法会抛出KeyError异常,附带参数key

  • 如果default_factory不为None,则它被(不带参数地)调用来为key提供一个默认值,这个值和key作为一对键值对被插入到字典中,并作为本方法的返回值返回

3、 default_factory

如果不存在,该对象会自动插入一个默认数据类型来代替

3.1 list

使用 list 作为 default_factory,很轻松地将(键-值对组成的)序列转换为(键-列表组成的)字典

from collections import defaultdict

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
# 第一种创建方法
d = defaultdict(list)
for k, v in s:
    d[k].append(v)

print(d)
print(d["green"])  # 如果不存在,返回空列表,并且创建该对象
print(sorted(d.items()))

# 第二种创建方法
d_ = {}
for k, v in s:
    d_.setdefault(k, []).append(v)

print(d_)

可以对字典中的值进行列表的所有操作

当每个键第一次遇见时,它还没有在字典里面,所以自动创建该条目,即调用default_factory方法,返回一个空的 list。 list.append() 操作添加值到这个新的列表里。当再次存取该键时,就正常操作,list.append() 添加另一个值到列表中。这个计数比它的等价方法dict.setdefault()要快速和简单

3.2 int

设置 default_factory为int,使defaultdict用于计数(类似其他语言中的 bag或multiset)

from collections import defaultdict

s = "mississippi"
# 创建方法
d = defaultdict(int)
for k in s:
    d[k] += 1  # 计数作用
print(d)
3.3 set

设置 default_factory 为 set 使 defaultdict 用于构建 set 集合

from collections import defaultdict

s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
# 创建方法
d = defaultdict(set)
for k, v in s:
    d[k].add(v)
print(d)
3.4 自定义对象
from collections import defaultdict


class Test:

    def printN(self):
        print(self.n)

    def setN(self, i):
        self.n = i


name = "abcdefghij"
d = defaultdict(Test)
for i in range(10):
    d[name[i]].setN(i)
d["a"].printN()  # 输出数值
print(d)
七、 ChainMap 1、 简介

一个ChainMap类是为了将多个映射快速的链接到一起,这样它们就可以作为一个单元处理。它通常比创建一个新字典和多次调用 update() 要快很多

这个类可以用于模拟嵌套作用域,并且在模版化的时候比较有用

创建对象:

cm = ChainMap(*maps)  # 传入映射对象

一个ChainMap 将多个字典或者其他映射组合在一起,创建一个单独的可更新的视图。 如果没有 maps 被指定,就提供一个默认的空字典,这样一个新链至少有一个映射

底层映射被存储在一个列表中。这个列表是公开的,可以通过 maps 属性存取和更新。没有其他的状态

搜索查询底层映射,直到一个键被找到。不同的是,写,更新和删除只操作第一个映射

一个 ChainMap 通过引用合并底层映射。 所以,如果一个底层映射更新了,这些更改会反映到ChainMap

支持所有常用字典方法。另外还有一个 maps 属性(attribute),一个创建子上下文的方法(method), 一个存取它们首个映射的属性(property)

2、 常用方法 方法 作用 maps 一个可以更新的映射列表 new_child(m=None, **kwargs) 如果指定了m则添加映射到对象前面,返回新映射 parents 返回一个新的 ChainMap 包含所有的当前实例的映射,跳过第一个映射

代码实例:

from collections import ChainMap

cm = ChainMap({"h": 1})
print(cm.maps)  # 返回列表
print(cm.new_child({"a": 2, "b": 3}))  # 添加映射
print(list(cm))  # 只返回键,不返回值
print(cm.new_child({"a": 2}).new_child({"b": 4}).parents)  # 返回除了第一个以外的其他对象

对于ChainMap对象,我们可以直接使用键取值,也可以直接使用字典的其他方法,就像它是一个单一的字典

此优点的作用,可以将配置文件读取后存储在此对象中,直接查找映射更加方便

八、 UserDict

用作字典对象的外包装。对这个类的需求已部分由直接创建 dict 的子类的功能所替代;不过,这个类处理起来更容易,因为底层的字典可以作为属性来访问

dic = UserDict([initialdata]) 

模拟字典的类。 这个实例的内容保存在一个常规字典中,它可以通过UserDict实例的 data 属性来访问。 如果提供了 initialdata,则 data 会用其内容来初始化;请注意对 initialdata 的引用将不会被保留,以允许它被用于其他目的

print(type(dic), type(dic.data))  # 使用data属性返回字典数据
九、 UserList

对这个类的需求已部分由直接创建list的子类的功能所替代;不过,这个类处理起来更容易,因为底层的列表可以作为属性来访问

lis = UserList([list])

模拟一个列表。这个实例的内容被保存为一个正常列表,通过 UserListdata 属性存取。实例内容被初始化为一个 list 的copy,默认为 [] 空列表。 list 可以是迭代对象,比如一个Python列表,或者一个 UserList对象

可以使用data属性访问UserList里面的内容

子类化的要求: UserList 的子类需要提供一个构造器,可以无参数调用,或者一个参数调用。返回一个新序列的列表操作需要创建一个实现类的实例。它假定了构造器可以以一个参数进行调用,这个参数是一个序列对象,作为数据源

如果一个分离的类不希望依照这个需求,所有的特殊方法就必须重写;请参照源代码进行修改

十、 UserString

用作字符串对象的外包装。对这个类的需求已部分由直接创建 str的子类的功能所替代;不过,这个类处理起来更容易,因为底层的字符串可以作为属性来访问

str_ =  UserString(seq)

模拟一个字符串对象。这个实例对象的内容保存为一个正常字符串,通过 UserStringdata 属性存取。实例内容初始化设置为 seq 的copy。seq 参数可以是任何可通过内建 str() 函数转换为字符串的对象

可以使用data属性来访问UserString 返回字符串

上一篇:NLP教程(1) - 词向量、SVD分解与Word2Vec
下一篇:没有了
网友评论