python中的 collections 模块(用法、详解、底层原理,示例等)

这篇具有很好参考价值的文章主要介绍了python中的 collections 模块(用法、详解、底层原理,示例等)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、collections 模块中的 defaultdict

1.1 defaultdict 功能

可以设置一个默认值作为字典中新key的默认值。该默认值可以是任何对象, 包括函数、列表、元组、集合等。默认值不需要像dict那样事先定义,因为它在需要的时候会自动创建
使用defaultdict,可以简化代码并提高代码的可读性,而且可以防止KeyError异常的出现。同时,defaultdict的性能与普通字典相当,因为底层实现并不影响字典的性能。

1.2 底层原理

重写了字典的__missing__方法。当访问字典中不存在的key时,__missing__方法负责返回默认值。因此,defaultdict通过继承dict,重载了__missing__方法,以提供默认值。

1.3 defaultdict 源码

class defaultdict(dict):
    """
    defaultdict(default_factory[, ...]) --> dict with default factory
    
    The default factory is called without arguments to produce
    a new value when a key is not present, in __getitem__ only.
    A defaultdict compares equal to a dict with the same items.
    All remaining arguments are treated the same as if they were
    passed to the dict constructor, including keyword arguments.
    """
    def copy(self): # real signature unknown; restored from __doc__
        """ D.copy() -> a shallow copy of D. """
        pass

    def __copy__(self, *args, **kwargs): # real signature unknown
        """ D.copy() -> a shallow copy of D. """
        pass

    def __getattribute__(self, *args, **kwargs): # real signature unknown
        """ Return getattr(self, name). """
        pass

    def __init__(self, default_factory=None, **kwargs): # known case of _collections.defaultdict.__init__
        """
        defaultdict(default_factory[, ...]) --> dict with default factory
        
        The default factory is called without arguments to produce
        a new value when a key is not present, in __getitem__ only.
        A defaultdict compares equal to a dict with the same items.
        All remaining arguments are treated the same as if they were
        passed to the dict constructor, including keyword arguments.
        
        # (copied from class doc)
        """
        pass

    def __missing__(self, key): # real signature unknown; restored from __doc__
        """
        __missing__(key) # Called by __getitem__ for missing key; pseudo-code:
          if self.default_factory is None: raise KeyError((key,))
          self[key] = value = self.default_factory()
          return value
        """
        pass

    def __reduce__(self, *args, **kwargs): # real signature unknown
        """ Return state information for pickling. """
        pass

    def __repr__(self, *args, **kwargs): # real signature unknown
        """ Return repr(self). """
        pass

    default_factory = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
    """Factory for default value called by __missing__()."""

1.4 简单使用和解释以及举例

# ======================================================
from collections import defaultdict

data_dic = defaultdict(list)       # default_factory默认是None, 这里default_factory默认是None赋值为列表
data_dic['name'].append("java")
data_dic['name'].append("python")
data_dic['name'].append("go")
data_dic['test_num'].append(1)
data_dic['test_num'].append(2)

# 虽然default_factory是list,但是它并不限制data_dic中键的类型,可以添加任何类型的键和值
data_dic['category'] = "IT"

print(data_dic)
# 打印的是一个defaultdict的对象,和字典一样的用法,也可以用 dict(data_dic) 将其转化为字典,但没必要,defaultdict对象和字典一样的用法
# 打印结果:defaultdict(<class 'list'>, {'name': ['java', 'python', 'go'], 'test_num': [1, 2], 'category': 'IT'})
print(data_dic['category'])

# data_dic中还没有 age 这个键,那么default_factory就会自动生成一个空列表作为该键的值
print(data_dic['age'])

2、collections 模块中的 OrderedDict

2.1 OrderedDict 功能

OrderedDict是Python中collections模块中的一种字典,它可以按照元素添加的顺序来存储键值对,保证了元素的顺序性。 与Python中普通字典不同的是,OrderedDict中的元素顺序是有序的,而且支持所有字典的操作。
OrderedDict类的优点是能够维护元素的有序性,缺点是存储元素时需要使用双向链表,因此需要比字典类占用更多的内存空间
字典所拥有的方法 OrderedDict 也同样拥有文章来源地址https://www.toymoban.com/news/detail-861613.html

2.2 OrderedDict 底层原理

OrderedDict底层原理是通过维护一个双向链表来实现的,该链表按照元素添加的顺序来存储键值对。
除了维护一个双向链表外,OrderedDict还维护了一个字典,在字典中存储了键值对的映射关系,以支持快速查找和删除操作。
因此,OrderedDict的底层实现是比较复杂的,但是它可以保证元素的顺序性,并且支持字典的所有操作。

每个元素都是一个节点,包含该元素的值、键和哈希值。每个节点还维护了两个指针,分别指向前一个节点和后一个节点。
当向OrderedDict中添加元素时,新元素将被添加到链表的末尾,并成为新的尾节点。
如果添加的元素已经存在于OrderedDict中,那么该元素将被删除然后被重新添加到链表的末尾,从而保证了元素的有序性。

2.3 OrderedDict 示例

  • 有序字典,按照元素添加顺序打印键值对
from collections import OrderedDict

d = OrderedDict()
d['python'] = 1
d['java'] = 2
d['go'] = 3
d['php'] = 4

for key, value in d.items():
    print(key, value)

# 打印结果
# python 1
# java 2
# go 3
# php 4
  • 用 OrderedDict 实现先进先出的队列
from collections import OrderedDict


class FIFO(OrderedDict):
    def __init__(self, capacity):
        super().__init__()
        self.capacity = capacity

    def __setitem__(self, key, value):
        if len(self) >= self.capacity:  # 容量已满
            self.popitem(last=False)  # 删除最早的元素,即队首元素
        super().__setitem__(key, value)


q = FIFO(3)
q['a'] = 1
q['b'] = 2
q['c'] = 3
print(q)  # 输出:FIFO([('a', 1), ('b', 2), ('c', 3)])
q['d'] = 4
print(q)  # 输出:FIFO([('b', 2), ('c', 3), ('d', 4)])
定义了一个FIFO类,该类继承了OrderedDict,并重载了__setitem__方法,实现了一个先进先出的队列。
当队列已满时,每次添加新元素时,会删除最早添加的元素,从而使队列长度保持不变。
在代码中,当队列长度已经达到最大长度时,通过调用self.popitem(last=False)方法删除最早添加的元素,
即队首元素,从而腾出位置来添加新元素。
  • popitem()
    popitem()方法用于弹出最后插入的元素。它接受一个可选的参数last,用于指定弹出的是最后插入的元素还是第一个插入的元素。
from collections import OrderedDict

ordered_dict = OrderedDict({'a': 1, 'c': 3, 'b': 2})
print(ordered_dict.popitem())  # ('b', 2)
print(ordered_dict.popitem(last=False))  # ('a', 1)

  • move_to_end()
move_to_end()方法可以将OrderedDict中的某个元素移动到双向链表的尾部或头部。
它接受两个可选参数,一个是key,指定要移动的元素;另一个是last,指定移动方向,
如果last为True,则移动到链表的末尾;
如果last为False,则移动到链表的头部。
from collections import OrderedDict

ordered_dict = OrderedDict({'a': 1, 'c': 3, 'b': 2})
ordered_dict.move_to_end('a')  # 将'a'元素移动到OrderedDict的末尾
print(list(ordered_dict.keys()))  # ['c', 'b', 'a']
ordered_dict.move_to_end('a', last=False)  # 将'a'元素移动到OrderedDict的头部
print(list(ordered_dict.keys()))  # ['a', 'c', 'b']

3、collections 模块中的 Counter

3.1 Counter 功能

  • Counter类型可以接受一个可迭代对象作为参数,并对其中的元素进行计数。同时,还可以接受一个字典对象作为参数,用于初始化计数器。
from collections import Counter

# 通过可迭代对象初始化计数器
c1 = Counter('hello')
print(c1)  # Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})

# 通过字典对象初始化计数器
c2 = Counter({'red': 4, 'blue': 2})
print(c2)  # Counter({'red': 4, 'blue': 2})

  • Counter类型还提供了一些有用的方法,例如:
    elements():返回一个迭代器,其中包含每个元素的重复次数。如果重复次数为0或负数,则不会返回该元素。
    most_common([n]):返回一个包含n个最常见元素及其计数的列表。如果n为空,则返回所有元素及其计数的列表。
    subtract([iterable-or-mapping]):从计数器中减去指定的元素或计数器。这个方法会修改计数器本身。
from collections import Counter

c = Counter('hello')
print(list(c.elements()))  # ['h', 'e', 'l', 'l', 'o']

print(c.most_common(2))  # [('l', 2), ('h', 1)]

c.subtract('world')
print(c)  # Counter({'l': 1, 'h': 1, 'e': 1, 'o': 1, 'w': -1, 'r': -1, 'd': -1})

3.2 Counter 底层原理

Counter类型的底层实现是基于哈希表的。

在初始化计数器时,它会创建一个空的哈希表,并将可迭代对象中的元素作为键,计数作为值,存储到哈希表中。
在对计数器进行修改时,它会直接在哈希表中查找相应的元素,并更新其计数值。
这种基于哈希表的实现方式,使得Counter类型在计数操作时具有很高的效率和灵活性。
例如,它可以对任意可哈希对象进行计数,包括数字类型、字符串、元组等。

3.3 Counter 优缺点

  • Counter类型的优点是:
可以对任意可哈希对象进行计数。
提供了一些有用的方法,方便对计数器进行操作。
在底层实现上,使用了哈希表,具有很高的效率和灵活性。
  • Counter类型的缺点是:
由于底层实现依赖于哈希表,因此在计数器比较大时,可能会占用较大的内存空间。
在计数器上进行一些复杂的操作,比如求差集、并集等,可能会比较困难。

3.4 Counter 示例

  • elements()
    elements()方法会返回一个迭代器,其中包含每个元素的重复次数。如果重复次数为0或负数,则不会返回该元素。
from collections import Counter

# 计算字符串中每个字符出现的次数,并按照出现次数升序输出
c = Counter('hello')
for element in c.elements():
    print(element, end=' ') # h e l l o

most_common([n])

  • most_common([n])方法会返回一个包含n个最常见元素及其计数的列表。如果n为空,则返回所有元素及其计数的列表。
from collections import Counter

# 计算字符串中每个字符出现的次数,并输出出现次数最多的前两个字符
c = Counter('hello')
print(c.most_common(2))  # [('l', 2), ('h', 1)]
  • subtract([iterable-or-mapping])
    subtract([iterable-or-mapping])方法会从计数器中减去指定的元素或计数器。这个方法会修改计数器本身。
from collections import Counter

# 对字符串进行计数,并减去另一个字符串中出现的字符
c = Counter('hello')
c.subtract('world')
print(c)  # Counter({'l': 1, 'h': 1, 'e': 1, 'o': 1, 'w': -1, 'r': -1, 'd': -1})

  • update([iterable-or-mapping])
    update([iterable-or-mapping])方法会将计数器更新为包括指定的元素或计数器。如果更新计数器后,某些元素的计数小于等于0,则会将这些元素从计数器中删除。
from collections import Counter

# 对字符串进行计数,并更新为另一个字符串中出现的字符的计数
c = Counter('hello')
c.update('world')
print(c)  # Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, 'w': 1, 'r': 1, 'd': 1})

  • subtract()与update()的组合使用
    通过subtract()方法可以将计数器中的元素减去指定的元素或计数器,而通过update()方法可以将计数器更新为包括指定的元素或计数器。这两个方法的组合使用,可以很方便地实现对计数器的增删操作。
from collections import Counter

# 对字符串进行计数,并将其中的'h'和'o'删除
c = Counter('hello')
c.subtract('ho')
c += Counter()  # 删除计数值为0或负数的元素
print(c)  # Counter({'l': 2, 'e': 1})

  • 使用Counter统计词频
# 统计test.txt中的词频
# 例如 test.txt 文件中的内容如下:
# python java c go
# java html vue
# c python go python

from collections import Counter

with open('test.txt', 'r') as f:
    word_counts = Counter(f.read().split())

print(word_counts.most_common(10))

# 结果
# [('python', 3), ('java', 2), ('c', 2), ('go', 2), ('html', 1), ('vue', 1)]

持续更新中。。。

到了这里,关于python中的 collections 模块(用法、详解、底层原理,示例等)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Python Lambda表达式的底层原理详解:编译、执行与优化机制

    Python Lambda表达式的底层原理详解:编译、执行与优化机制

    昨天面试被问到了lambda表达式的底层是怎么实现的,我直接脑子就空白了,因为平时只关注lambda的应用方式 在Python中,无论是普通函数还是Lambda函数,都会经过编译转换成字节码,解释器再执行这些字节码。 1.1 示例代码 通过 dis 模块,可以查看Lambda函数的字节码。这些字节

    2024年04月28日
    浏览(14)
  • Java基础:Collections.sort的两种用法详解

    Collections是⼀个⼯具类,sort是其中的静态⽅法,是⽤来对 List 类型进⾏排序的,它有两种参数形式:

    2024年02月10日
    浏览(12)
  • 【python】程序运行添加命令行参数argparse模块用法详解

    【python】程序运行添加命令行参数argparse模块用法详解

     很多时候,我们的程序要带参数来运行不同的功能,需要解析命令行参数。argparse模块能够很好的提供支持。 argparse是 python 自带的命令行参数解析包,用于解析命令行参数的标准模块。可以让人轻松编写用户友好的命令行接口,还会自动生成帮助和使用手册,并在用户给程

    2024年02月04日
    浏览(9)
  • Python中的睡眠函数用法详解

    Python中的睡眠函数用法详解 睡眠函数是Python中常用的函数之一,它允许程序在执行过程中暂停一段时间。在进行并发编程、定时任务或模拟等场景中,睡眠函数特别有用。本文将详细介绍Python中睡眠函数的用法,并提供相应的源代码。 Python中的睡眠函数由time模块提供,具体

    2024年02月05日
    浏览(13)
  • Python中的filter函数用法详解

    Python中的filter函数用法详解

    目录 引言 一、filter函数基本用法 二、filter函数应用场景 1、筛选符合条件的元素 2、数据清洗和预处理 3、复杂条件筛选 4、与其他函数结合使用 三、filter函数与lambda表达式 四、filter函数与列表推导式 五、总结 Python中的filter函数是一种内置的高效过滤器,用于从序列中筛选

    2024年02月21日
    浏览(8)
  • 【JAVA原理系列】Java String类中的三个替换方法replaceFirst、replaceAll和replace原理用法示例源码详解

    这里是三种字符串替换方法的原理: replaceFirst() 方法的原理是通过编译给定的正则表达式,然后使用编译后的模式创建一个匹配器对象,将该匹配器应用于目标字符串,并使用给定的替换字符串替换第一个匹配的子字符串。 replaceAll() 方法的原理与 replaceFirst() 类似,也是通过

    2024年04月16日
    浏览(10)
  • 25 Python的collections模块

    概述         在上一节,我们介绍了Python的sqlite3模块,包括:sqlite3模块中一些常用的函数和类。在这一节,我们将介绍Python的collections模块。collections模块是Python中的内置模块,它实现了特殊的容器数据类型,提供了Python的通用内建容器的替代选择。         使用co

    2024年02月08日
    浏览(6)
  • Python中的append()、add()、extend()、update()用法详解

    在列表中, append函数 用于向列表的末尾添加一个元素。例如: 需要注意的是,append函数只能添加一个元素,如果要添加多个元素,可以使用 extend函数 或者使用 加号运算符 : 在集合中,append函数并不存在。如果要向集合中添加元素,可以使用 add函数 : 需要注意的是,集

    2024年04月25日
    浏览(11)
  • python中的range函数|python中的range函数|range()函数详解|Python中range(len())的用法

    range() 是 Python 内置的一个函数,用于生成一个整数序列。具体来说,它的定义如下: start、stop、step 分别表示序列的起始值、终止值和步长。start 和 step 是可选参数,如果不指定则默认为 0 和 1。 当只传入一个参数时,表示生成从 0 开始、小于该参数的整数序列。例如: 这

    2024年02月07日
    浏览(13)
  • docker 的整体架构及各模块组件 《深入docker底层原理》

    docker 的整体架构及各模块组件 《深入docker底层原理》

    Docker 是一个 C/S 模式的架构,后端是一个松耦合架构,模块各司其职。 1、用户是使用 Docker Client 与 Docker Daemon 建立通信,并发送请求给后者。 2、Docker Daemon 作为 Docker 架构中的主体部分,首先提供 Docker Server 的功能使其可以接受 Docker Client 的请求。 3、Docker Engine 执行 Docke

    2024年02月12日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包