c语言编程笔录

首页 >   > 笔记大全

笔记大全

Python Default Set 优雅高效的数据结构实现

更新时间:2023-11-24

什么是 Default Set?

默认集合(Default Set)是 Python 3.3 中引入的一种新的数据类型。它是一种类似于字典(dict)的结构,但默认值是一个可调用对象(callable)函数。不同于字典的是,Default Set 不需要使用者初始设定键值。如果某个键不存在时返回预设的值。

from collections import defaultdict

# 以 int 类型作为默认值
d = defaultdict(int)
d['one'] = 1
d['two'] = 2
d['three'] += 1
print(d)
# 输出 defaultdict(, {'one': 1, 'two': 2, 'three': 1})

# 以 lambda 函数为默认值
d = defaultdict(lambda: 'Unknown')
d['name'] = 'Sandy'
d['age'] = 20
print(d['gender'])
# 输出 Unknown

什么时候使用 Default Set?

在默认情况下,尝试访问不存在的键会导致 KeyError 的抛出。但是在某些情况下,我们希望自动获取一个默认值,以便快速处理。在这种情况下,Default Set 就派上用场了。

例如,在自然语言处理(NLP)中,文本可能会被转换为向量。当我们遇到新单词时,我们需要分配一个新的标识符,并添加它作为向量中的新维度。通过创建一个默认为零的 Default Set 并使用该字典,我们可以轻松处理这个问题。

from collections import defaultdict

vector_dict = defaultdict(lambda: len(vector_dict))
word_list = ['apple', 'banana', 'apple', 'orange']
vector = [0] * len(word_list)
for i, word in enumerate(word_list):
    dimension = vector_dict[word]
    vector[dimension] += 1
print(vector)
# 输出 [2, 1, 1]

如何为 Default Set 提供默认值?

我们可以通过两种方式向 Default Set 提供默认值。

  • 使用内置函数提供默认值
  • 使用可调用对象(callable)函数提供默认值

使用内置函数提供默认值:

from collections import defaultdict

d = defaultdict(int)
print(d['new_key'])
# 输出 0

d.default_factory = list
print(d['new_key'])
# 输出 []

使用可调用对象(callable)函数提供默认值:

from collections import defaultdict

def provide_default():
    return 'Default Value'

d = defaultdict(provide_default)
print(d['new_key'])
# 输出 Default Value

Default Set 和普通字典的比较

Default Set 带来的最大好处是它可以将值的初始化和添加分开。这使得代码更易于理解和维护,并可以显著提高代码的性能。

from collections import defaultdict
import timeit

# 使用普通字典
start = timeit.default_timer()
d = {}
for i in range(1000000):
    if i % 10 == 0:
        d[i] = 1
    else:
        d[i] += 1
end = timeit.default_timer()
print('普通字典时间:', end - start)

# 使用 Default Set
start = timeit.default_timer()
d = defaultdict(int)
for i in range(1000000):
    if i % 10 == 0:
        d[i] = 1
    else:
        d[i] += 1
end = timeit.default_timer()
print('Default Set时间:', end - start)

在上述示例中,我们可以看到 Default Set 的处理速度明显更快。因为它避免了显式初始化和 "if key not in dictionary" 这样的循环判断。