在Think中,作者引入了defaultdict。以下是一本有关defaultdict的书的摘录
如果要制作列表字典,通常可以使用defaultdict编写更简单的代码。在我练习12-2的解决方案中,您可以从sets.py获得,我制作了一个字典,从一个排序的字母字符串映射到可以用这些字母拼写的单词列表。例如,opst映射到列表“opts”、“post”、“spot”、“post”、“top”、“top”。这是原始代码: def all_anagrams(文件名):d= {}表示打开的行(文件名):word = line.strip().lower() t=签名( word )如果t不在d: dt =word: dt.append(word)返回d 这可以使用setdefault进行简化,您可以在练习11-2中使用它: def all_anagrams(文件名):d= {} (文件名):word = line.strip().lower() t= signature(word) d.setdefault(t,[]).append(word)返回d 这种解决方案的缺点是,它每次都会生成一个新列表,而不管是否需要它。对于列表来说,这没什么大不了的,但是如果工厂函数是复杂的,它可能是。我们可以避免这个问题,并使用defaultdict简化代码: def all_anagrams(文件名):d=defaultdict(列表),用于打开(文件名):word = line.strip().lower() t= signature(word) dt.append(word)返回d
下面是signature函数的定义:
def signature(s):
"""Returns the signature of this string.
Signature is a string that contains all of the letters in order.
s: string
"""
# TODO: rewrite using sorted()
t = list(s)
t.sort()
t = ''.join(t)
return t关于第二种解决方案,我理解的是setdefault检查t (单词的签名)是否作为密钥存在,如果不是,它将其设置为密钥,并将空列表设置为其值,然后append将单词追加到其中。如果存在t,则setdefault返回它的值(至少有一个项的列表,它是一个表示单词的字符串),append将这个单词追加到这个列表中。
关于第三种解决方案,我理解的是d,它代表一个defaultdict,它使t成为一个键,并将一个空列表设置为它的值(如果t还没有作为键存在),那么单词就会被追加到列表中。如果t已经存在,则返回它的值(列表),并将单词追加到该值。
第二个和第三个解决方案的区别是什么?这意味着,无论是否需要,第二个解决方案中的代码每次都会生成一个新列表?setdefault是如何对此负责的?使用defaultdict如何使我们避免这个问题?第二个和第三个解决方案有什么不同?
发布于 2017-08-20 01:45:29
“每次生成一个新列表”意味着每次调用setdefault(t, [])时,都会创建一个新的空list ( []参数)作为默认值,以防需要它。使用defaultdict可以避免这样做的需要。
虽然这两种解决方案都返回一个字典,但使用defaultdict的解决方案实际上返回了一个defaultdict(list),它是内置dict类的一个子类。这通常不是问题。最显著的效果可能是如果您print()返回的对象,因为这两个输出看起来非常不同。
如果出于任何原因不希望这样做,可以将函数的最后一条语句更改为:
return dict(d)将创建的defaultdict(list)转换为常规dict。
https://stackoverflow.com/questions/45777611
复制相似问题