collections
模块是 Python 标准库的一部分,提供了多种用于处理集合数据结构的工具,其中 defaultdict
是一个非常常用的容器类。它是 字典 的一个子类,可以在访问不存在的键时返回一个默认值,而不是抛出 KeyError
异常。除此之外,collections
模块还提供了许多类似于 defaultdict
的工具,每个工具都具有不同的功能和应用场景。
下面是 collections
模块中的一些其他常用类型和方法:
1. Counter
- 作用:
Counter
是一个字典子类,用于计数可哈希对象的出现次数。它将元素作为键,出现的次数作为值。
常见用法
from collections import Counter
# 创建 Counter 对象
counter = Counter(["a", "b", "a", "c", "b", "a"])
print(counter) # 输出:Counter({'a': 3, 'b': 2, 'c': 1})
# 访问元素的计数
print(counter["a"]) # 输出:3
# 使用 most_common() 获取出现频率最高的元素
print(counter.most_common(2)) # 输出:[('a', 3), ('b', 2)]
特性
- 可以用于统计元素的频率。
- 提供了
most_common()
方法来返回出现频率最高的元素。
2. deque
- 作用:
deque
是一个双端队列(double-ended queue)。它允许从两端快速添加和删除元素,比列表更高效。
常见用法
from collections import deque
# 创建 deque 对象
d = deque([1, 2, 3])
# 从右端添加元素
d.append(4)
print(d) # 输出:deque([1, 2, 3, 4])
# 从左端添加元素
d.appendleft(0)
print(d) # 输出:deque([0, 1, 2, 3, 4])
# 从右端删除元素
d.pop()
print(d) # 输出:deque([0, 1, 2, 3])
# 从左端删除元素
d.popleft()
print(d) # 输出:deque([1, 2, 3])
特性
- 高效的双端操作:
deque
允许在两端进行 O(1) 的添加和删除操作。 - 可以作为队列或栈使用。
3. namedtuple
- 作用:
namedtuple
创建一个具名元组类。元组是不可变的,但namedtuple
允许你通过命名字段来访问元组的元素,使代码更加可读。
常见用法
from collections import namedtuple
# 创建一个具名元组类型
Point = namedtuple("Point", ["x", "y"])
# 创建具名元组实例
p = Point(1, 2)
# 通过名称访问元素
print(p.x) # 输出:1
print(p.y) # 输出:2
# 也可以像普通元组一样按索引访问
print(p[0]) # 输出:1
特性
- 可以像访问对象属性一样访问元组的元素,增加可读性。
- 提供了类似于类的字段名访问方式。
4. OrderedDict
- 作用:
OrderedDict
是一个字典子类,记住插入顺序(在 Python 3.7+ 中,普通字典dict
也保留插入顺序,但OrderedDict
提供了额外的功能)。它提供了一些额外的操作方法。
常见用法
from collections import OrderedDict
# 创建 OrderedDict
od = OrderedDict([("one", 1), ("two", 2), ("three", 3)])
# 打印顺序
print(od) # 输出:OrderedDict([('one', 1), ('two', 2), ('three', 3)])
# 你可以像普通字典一样操作 OrderedDict
od["four"] = 4
print(od) # 输出:OrderedDict([('one', 1), ('two', 2), ('three', 3), ('four', 4)])
# 使用 move_to_end() 来改变顺序
od.move_to_end("two")
print(od) # 输出:OrderedDict([('one', 1), ('three', 3), ('four', 4), ('two', 2)])
特性
- 保留插入顺序:与
defaultdict
或常规字典不同,OrderedDict
明确保证字典条目的插入顺序。 - 额外方法:提供如
move_to_end()
、popitem()
等操作方法。
5. ChainMap
- 作用:
ChainMap
用于将多个字典(或映射对象)合并成一个单一的视图。这意味着可以在多个字典之间快速查找,而不需要合并它们。
常见用法
from collections import ChainMap
# 创建多个字典
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
# 创建 ChainMap
chain = ChainMap(dict1, dict2)
# 查找时优先从第一个字典查找
print(chain["b"]) # 输出:2, 因为 dict1 中的 b 会优先
print(chain["c"]) # 输出:4, 从 dict2 查找
特性
- 多字典合并:
ChainMap
将多个字典(或其他映射类型)合并成一个逻辑上单一的视图,但每个字典仍然保持独立。 - 允许在多个字典中查找,查找顺序从第一个字典开始。
6. UserDict
和 UserList
- 作用:
UserDict
和UserList
是可以被继承的类,它们允许用户自定义字典和列表的行为。它们为需要修改数据类型行为的用户提供了一个基础类。
常见用法
from collections import UserDict
class MyDict(UserDict):
def __getitem__(self, key):
print(f"Accessing key: {key}")
return super().__getitem__(key)
d = MyDict({"a": 1, "b": 2})
print(d["a"]) # 输出:Accessing key: a \n 1
特性
- 继承和扩展:可以通过继承
UserDict
或UserList
来扩展默认行为,提供自定义的方法和逻辑。
-
defaultdict
介绍
定义
defaultdict
是 dict
的一个子类,和普通的字典一样存储键值对。但最大的不同在于,它可以为不存在的键提供一个默认值,而不是抛出 KeyError
异常。这使得你可以避免在访问字典的某个键时检查该键是否存在。
基本语法
from collections import defaultdict
# 创建一个 defaultdict,指定默认值的类型
d = defaultdict(int) # 默认值为 0(int 的默认值)
工作原理
defaultdict
会根据你传入的默认工厂函数来生成默认值。如果你访问一个不存在的键,defaultdict
会调用该工厂函数返回一个值,而不是抛出异常。- 工厂函数是你传入的类型或自定义的可调用对象。例如,可以传入
int
(默认值为 0)、list
(默认值为空列表),或者自定义的函数。
常见用法
1. 使用 int
作为默认工厂函数
from collections import defaultdict
# 创建一个 defaultdict,默认值为 0
d = defaultdict(int)
# 访问一个不存在的键时,返回默认值 0
print(d["a"]) # 输出:0
# 为键赋值
d["a"] += 1
print(d) # 输出:defaultdict(<class 'int'>, {'a': 1})
- 在这个例子中,
d["a"]
最开始没有存在,所以返回了默认值0
。之后我们对键"a"
的值进行了加法操作。
2. 使用 list
作为默认工厂函数
from collections import defaultdict
# 创建一个 defaultdict,默认值为 []
d = defaultdict(list)
# 访问不存在的键时,返回一个空列表
d["fruits"].append("apple")
d["fruits"].append("banana")
print(d) # 输出:defaultdict(<class 'list'>, {'fruits': ['apple', 'banana']})
- 这里我们使用
list
作为默认工厂函数,这样当我们访问一个不存在的键时,它会返回一个空的列表。然后我们可以对这个列表进行append
操作。
3. 使用自定义函数作为默认工厂函数
from collections import defaultdict
# 定义一个自定义工厂函数
def default_value():
return "default value"
# 创建一个 defaultdict,使用自定义函数作为默认值
d = defaultdict(default_value)
print(d["key"]) # 输出:default value
- 在这个例子中,
default_value()
是我们自定义的工厂函数,当访问一个不存在的键时,它会返回 "default value"。
常见应用场景
-
处理计数问题
defaultdict(int)
常用于计数任务,它可以自动为每个新键初始化计数器,而不需要手动检查键是否存在。from collections import defaultdict words = ["apple", "banana", "apple", "orange", "banana", "banana"] count = defaultdict(int) for word in words: count[word] += 1 print(count) # 输出:defaultdict(<class 'int'>, {'apple': 2, 'banana': 3, 'orange': 1})
-
构建分组字典
如果你想将元素分组(如按照字母分组或根据某个特征分组),defaultdict(list)
可以非常方便地完成这个任务。from collections import defaultdict # 假设有一些学生及其成绩 students = [("Alice", "A"), ("Bob", "B"), ("Charlie", "A"), ("David", "C")] # 创建 defaultdict,将学生成绩分组 grade_groups = defaultdict(list) for student, grade in students: grade_groups[grade].append(student) print(grade_groups) # 输出:defaultdict(<class 'list'>, {'A': ['Alice', 'Charlie'], 'B': ['Bob'], 'C': ['David']})
这个例子中,我们使用
defaultdict(list)
将学生根据成绩分组。如果某个成绩之前没有记录,defaultdict
会自动为该成绩键创建一个空列表。
defaultdict
的优点
- 简化代码:避免了在字典访问时频繁检查键是否存在,减少了
if
判断语句。 - 减少错误:如果字典中某个键不存在,
defaultdict
会自动为其分配默认值,避免了KeyError
异常。 - 更高效的处理:特别适合用于计数、分组等任务,能够有效避免重复代码。
总结
collections
模块提供了多种便利的工具,扩展了 Python 原生数据类型(如字典、列表、元组等)的功能,帮助开发者在各种场景下更加高效地操作数据。以下是一些常见类型:
defaultdict
:提供默认值的字典,避免KeyError
。Counter
:用于计数元素的字典子类。deque
:高效的双端队列。namedtuple
:具名元组,提供更加直观的字段访问方式。OrderedDict
:保留插入顺序的字典。ChainMap
:多个字典的合并视图。UserDict
和UserList
:用于自定义字典或列表行为的基类。
这些工具能够大大提高代码的简洁性和性能,使得 Python 在处理集合数据时更加灵活和高效。
标签:defaultdict,输出,python,collections,print,默认值,字典 From: https://www.cnblogs.com/lmc7/p/18642452