深入python的set和dict 您所在的位置:网站首页 python中set和dict的区别 深入python的set和dict

深入python的set和dict

2024-06-28 02:31| 来源: 网络整理| 查看: 265

深入python的set和dict dict的abc继承关系

在 Python 中,dict 类是内置的字典类型,用于存储键值对。Python 的 collections.abc 模块提供了一组抽象基类(ABCs),这些基类定义了各种容器类型应该实现的方法。这些抽象基类可以用来检查一个类是否提供了特定的接口,即它是否实现了特定的方法。

dict 的 ABC 继承关系

dict 类主要与以下几个抽象基类相关:

collections.abc.Mapping:

这是所有映射类型的抽象基类。映射对象表示键到值的映射,并且它们保持元素的插入顺序。dict 是这个类的一个具体实现,它提供了映射所需的所有方法,如 __getitem__, __setitem__, __delitem__, __iter__, 和 __len__。

collections.abc.MutableMapping:

这个抽象基类扩展了 Mapping,添加了可以修改映射的方法,如 pop, popitem, clear, update, 和 setdefault。dict 同样实现了这个接口,使其不仅可以读取,还可以修改字典内容。

collections.abc.Collection:

这个抽象基类是 Iterable, Sized, 和 Container 的综合体。它提供了一些基本的集合操作。dict 通过继承 Mapping 间接继承了 Collection。

collections.abc.Iterable:

这个接口要求实现 __iter__() 方法,返回一个迭代器。dict 通过其键、值或键值对可以被迭代。

collections.abc.Sized:

这个接口要求实现 __len__() 方法,返回容器中元素的数量。dict 实现了这个方法,可以通过 len() 函数获取字典的大小。

collections.abc.Container:

这个接口要求实现 __contains__() 方法,用于检查容器是否包含某个元素。在 dict 的情况下,这通常用来检查某个键是否存在。 总结

dict 类是 Python 中的一个非常强大的内置数据结构,它不仅实现了 MutableMapping 的所有方法,还通过继承链实现了其他几个重要的抽象基类的方法。这些抽象基类为 dict 提供了规范的行为和接口,使得 dict 可以与其他实现了相同接口的自定义类在多态性方面兼容。这种设计也便于开发者在创建自己的类时,通过继承或实现这些抽象基类来确保它们的类具有一致的接口和行为。

dict的常用方法

Python 中的 dict 类提供了多种方法来操作和管理字典。这些方法可以帮助你有效地添加、删除、查找和操作字典中的键值对。以下是一些最常用的 dict 方法:

1. get(key[, default])

返回字典中键 key 对应的值。如果键不存在,则返回 default,默认为 None。

d = {'a': 1, 'b': 2} print(d.get('a')) # 输出: 1 print(d.get('c', 3)) # 输出: 3 2. setdefault(key[, default])

如果字典中包含有给定键,则返回该键对应的值。否则,将键值对 key = default 插入到字典中,并返回 default。

d = {'a': 1, 'b': 2} print(d.setdefault('a', 3)) # 输出: 1 print(d.setdefault('c', 3)) # 输出: 3 print(d) # 输出: {'a': 1, 'b': 2, 'c': 3} 3. update([other])

更新字典,添加或覆盖来自另一个字典或可迭代对象(必须是键值对)的键值对。

d = {'a': 1, 'b': 2} d.update({'b': 10, 'c': 3}) print(d) # 输出: {'a': 1, 'b': 10, 'c': 3} 4. keys()

返回一个字典视图对象,包含字典的键。

d = {'a': 1, 'b': 2} print(d.keys()) # 输出: dict_keys(['a', 'b']) 5. values()

返回一个字典视图对象,包含字典的值。

d = {'a': 1, 'b': 2} print(d.values()) # 输出: dict_values([1, 2]) 6. items()

返回一个字典视图对象,包含字典的键值对。

d = {'a': 1, 'b': 2} print(d.items()) # 输出: dict_items([('a', 1), ('b', 2)]) 7. pop(key[, default])

删除字典给定键 key 所对应的值,返回这个值。如果键不存在,则返回 default,如果没有指定 default,则抛出 KeyError。

d = {'a': 1, 'b': 2} print(d.pop('b')) # 输出: 2 print(d) # 输出: {'a': 1} 8. popitem()

随机返回并删除字典中的一个键值对(在 Python 3.7+ 中是最后插入的键值对)。

d = {'a': 1, 'b': 2} print(d.popitem()) # 输出: ('b', 2) print(d) # 输出: {'a': 1} 9. clear()

清空字典中的所有项。

d = {'a': 1, 'b': 2} d.clear() print(d) # 输出: {} 10. copy()

返回字典的一个浅复制。

d = {'a': 1, 'b': 2} d2 = d.copy() print(d2) # 输出: {'a': 1, 'b': 2}

这些方法使得 dict 类在 Python 中非常灵活和强大,能够满足大多数与字典相关的需求。

dict的子类

在 Python 中,dict 类是一个非常强大的内置类型,它提供了基本的映射功能。除了标准的 dict 类,Python 的标凈库也提供了几个有用的 dict 子类,这些子类扩展了 dict 的功能以满足特定的用途。下面是一些常见的 dict 子类:

1. collections.OrderedDict

在 Python 3.7 之前,标准的 dict 类不保证键的顺序。OrderedDict 是一个特殊的字典子类,它保持了元素被添加的顺序。在 Python 3.7 及以后,标准的 dict 类已经被改进,现在默认保持插入顺序,但 OrderedDict 仍然有一些特殊功能,如它的 popitem 方法可以用来弹出第一个或最后一个元素。

2. collections.defaultdict

defaultdict 是一个字典子类,它提供了一个默认值,用于字典试图访问不存在的键时。你可以提供一个函数,这个函数在需要时会被调用来提供默认值。这可以简化代码并避免检查键是否存在。

3. collections.Counter

Counter 是一个专门用于计数的字典子类。它用于计算可哈希对象(如列表中的元素)的出现次数。它包含了多个有用的计数相关的方法和模式,如 most_common() 来获取出现次数最多的元素。

4. types.MappingProxyType

这不是一个真正的字典子类,而是一个返回字典的只读视图的函数。这可以用来创建一个不可修改的字典视图,任何尝试修改视图的操作都会抛出异常。

示例代码

下面是这些 dict 子类的简单示例:

from collections import OrderedDict, defaultdict, Counter from types import MappingProxyType # OrderedDict ordered_dict = OrderedDict([('a', 1), ('b', 2), ('c', 3)]) print(ordered_dict) # 输出: OrderedDict([('a', 1), ('b', 2), ('c', 3)]) # defaultdict def_dict = defaultdict(int) # 默认值为 int,即 0 def_dict['a'] += 1 print(def_dict) # 输出: defaultdict(, {'a': 1}) # Counter counter = Counter(['a', 'b', 'a', 'c', 'b', 'a']) print(counter) # 输出: Counter({'a': 3, 'b': 2, 'c': 1}) print(counter.most_common(1)) # 输出: [('a', 3)] # MappingProxyType original_dict = {'a': 1, 'b': 2} read_only_dict = MappingProxyType(original_dict) print(read_only_dict) # 输出: {'a': 1, 'b': 2} # read_only_dict['a'] = 3 # 尝试修改会抛出 TypeError

这些子类通过提供额外的功能和特性,使得 dict 类在 Python 中的应用更加灵活和强大。

set和frozenset

在 Python 中,set 和 frozenset 都是内置的数据结构,用于存储唯一的元素。这两种类型的主要区别在于 set 是可变的,而 frozenset 是不可变的。这意味着一旦创建了 frozenset,就无法更改其内容(添加或删除元素),而 set 可以随时修改。

set

set 是一个无序的集合类型,支持数学上的标准集合操作,如并集、交集、差集和对称差集。set 可以使用大括号 {} 或者 set() 函数来创建。它主要用于去除重复元素、集合运算等场景。

常用的 set 操作包括: add(elem):向集合中添加一个元素。remove(elem):从集合中移除一个元素,如果元素不存在则抛出 KeyError。discard(elem):从集合中移除一个元素,如果元素不存在也不会抛出错误。pop():随机移除一个元素并返回该元素,如果集合为空则抛出 KeyError。clear():清空集合中的所有元素。union()、intersection()、difference()、symmetric_difference():执行并集、交集、差集和对称差集操作。 frozenset

frozenset 是不可变的,可以作为字典的键或者另一个集合的元素。它的行为和 set 类似,但不支持任何修改集合的操作,如添加或删除元素。frozenset 可以通过 frozenset() 函数创建。

frozenset 支持的操作主要是: 所有不修改集合的 set 操作,如 union()、intersection() 等。由于其不可变性,frozenset 可以用作字典的键。 示例代码 # 创建 set 和 frozenset s = set([1, 2, 3, 2, 1]) fs = frozenset([1, 2, 3, 2, 1]) print("set:", s) # 输出: set: {1, 2, 3} print("frozenset:", fs) # 输出: frozenset: frozenset({1, 2, 3}) # 修改 set s.add(4) print("Modified set:", s) # 输出: Modified set: {1, 2, 3, 4} # 尝试修改 frozenset (会抛出 AttributeError) # fs.add(4) # 集合运算 print("Union:", s.union(fs)) # 输出: Union: {1, 2, 3, 4} print("Intersection:", s.intersection(fs)) # 输出: Intersection: {1, 2, 3}

总的来说,set 和 frozenset 在 Python 中提供了强大的集合处理功能,选择使用哪一个取决于你是否需要修改集合的内容。

dict和set的实现原理

在 Python 中,dict(字典)和 set(集合)是基于哈希表的数据结构。这些数据结构的实现原理涉及到一系列有趣的技术,使它们在执行查找、插入和删除操作时非常高效。以下是这两种数据结构实现原理的概述:

1. 哈希表(Hash Table)

哈希表是一种使用哈希函数组织数据的数据结构,以便快速访问存储在表中的数据项。哈希函数将输入(例如字典的键或集合的元素)转换为存储位置的索引。

哈希冲突

当两个不同的输入值经过哈希函数处理后得到相同的输出索引时,就会发生哈希冲突。Python 的字典和集合通过以下方式处理哈希冲突:

开放寻址法:如果发生冲突,哈希表会尝试找到下一个空闲的槽位来存储新的元素。链地址法:每个槽位开始是一个链表的头节点。如果多个元素哈希到同一个槽位,它们会被添加到这个槽位的链表中。

Python 主要使用开放寻址法来解决冲突。

2. 动态调整大小

为了保持操作的高效性,Python 的 dict 和 set 会根据元素的数量动态调整哈希表的大小。这意味着当哈希表的负载因子(已存储的元素数与槽位总数的比率)达到一定阈值时,哈希表的容量会增加,通常是加倍。然后,现有元素会被重新哈希到新的槽位中。

3. 字典(dict)

Python 的字典存储键值对。它使用键的哈希值来确定存储位置:

键必须是可哈希的:这意味着键必须是不可变类型,如整数、浮点数、字符串、元组等。查找时间复杂度:在理想情况下,字典操作(插入、查找和删除)的时间复杂度为 O(1)。在最坏的情况下(例如,当所有键都哈希到同一个槽位时),这些操作的时间复杂度将退化到 O(n)。 4. 集合(set)

集合在内部实现上与字典非常相似,但它只存储键,没有值。集合用于存储唯一元素,并提供高效的成员检查、添加和删除操作。

元素也必须是可哈希的。操作的时间复杂度:与字典类似,集合的基本操作通常是 O(1),在哈希冲突极端的情况下会退化到 O(n)。 总结

Python 中的 dict 和 set 是基于高效的哈希表实现的,它们提供了快速的数据存取操作。这些结构的动态大小调整和冲突解决策略进一步优化了它们的性能,使得在大多数情况下,它们的操作都非常迅速。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有