Python 成长笔记

Python拾珍:7. defaultdict

2018-03-01  本文已影响7人  赵者也

collections 模块还提供了 defaultdict,它和字典相似,不同的是,如果你访问一个不存在的键,它会自动创建一个新值。

创建一个 defaultdict 对象时,需要提供一个用于创建新值的函数。用来创建对象的函数有时候被称为工厂(factory)函数。用于创建列表、集合以及其他类型对象的内置函数,都可以用作工厂函数:

示例代码

请注意,参数 list(是一个类对象),而不是 list()(一个新的列表)。你提供的函数直到访问不存在的键时,才会被调用:

访问不存在的键

新列表 t 也会加到字典中。所以,如果我们修改 t,改动也会在 d 中体现:

修改 t,改动也会在 d 中体现

如果创建一个由列表组成的字典,使用 defaultdict 往往能够帮助我们写出更简洁的代码。例如,我们创建一个字典,将排序的字面字符串映射到可以由那些字母拼写出来的单词列表。例如,‘opst’映射到列表['opts', 'post', 'pots', 'spot', 'stop', 'tops']。下面是原始的代码:

def all_anagrams(filename):
    d = {}
    for line in open(filename):
        word = line.strip().lower()
        t = signature(word)
        if t not in d:
            d[t] = [word]
        else:
            d[t].append(word)
    return d

这个函数可以用 setdefault 简化:

def all_anagrams(filename):
    d = {}
    for line in open(filename):
        word = line.strip().lower()
        t = signature(word)
        # if t not in d:
        #     d[t] = [word]
        # else:
        #     d[t].append(word)
        d.setdefault(t, []).append(word)
    return d

但这个解决方案有一个缺点,它不管是否需要,每次都会创建一个列表。对于列表来说,这并不算大问题,但如果工厂函数非常复杂,就可能成为问题。

我们可以使用 defaultdict 来避免这个问题,并进一步简化代码:

def all_anagrams(filename):
    # d = {}
    # for line in open(filename):
    #     word = line.strip().lower()
    #     t = signature(word)
    #     # if t not in d:
    #     #     d[t] = [word]
    #     # else:
    #     #     d[t].append(word)
    #     d.setdefault(t, []).append(word)
    # return d
    d = defaultdict(list)
    for line in open(filename):
        word = line.strip().lower()
        t = signature(word)
        d[t].append(word)
    return d

本文参考自《像计算机科学家一样思考Python (第2版)

上一篇下一篇

猜你喜欢

热点阅读