Python如何使用defaultdict创建一个字典的字典的列表

10 浏览
0 Comments

Python如何使用defaultdict创建一个字典的字典的列表

我如何使用defaultdict创建一个字典的字典的列表?我遇到了以下错误。

>>> from collections import defaultdict
>>> a=defaultdict()
>>> a["testkey"]=None
>>> a
defaultdict(None, {'testkey': None})
>>> a["testkey"]["list"]=[]
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'NoneType' object does not support item assignment

0
0 Comments

在Python中创建一个字典的字典的列表通常会遇到一些问题,但是我们可以通过使用defaultdict来解决这个问题。下面是一个示例,展示了如何使用defaultdict创建一个字典的字典的列表:

from collections import defaultdict
a = defaultdict()
a["testkey"] = defaultdict(list)
a["testkey"]["list"] = ["a", "b", "c"]

在这个示例中,我们首先导入了collections模块中的defaultdict类。然后我们创建了一个名为a的defaultdict对象。接着,我们向a中添加了一个键为"testkey"的项目,并将其值设置为一个新的defaultdict对象,这个对象的默认值是一个空列表。最后,我们通过a["testkey"]["list"]的方式向a中的字典的字典的列表中添加了一个名为"list"的键,其值是一个包含字符串"a"、"b"和"c"的列表。

这样,我们就成功创建了一个字典的字典的列表。在这个例子中,a的值为:

defaultdict(None, {'testkey': defaultdict(, {'list': ['a', 'b', 'c']})})

上面的代码确实可以实现我们的目标,但是在使用defaultdict的时候,将默认值设置为None的方式有些多余。另外,使用defaultdict和显式值设置的混合方式可能有些笨拙。因此,有人提出了一种更好的方式,即通过将一个自定义函数传递给第一个defaultdict来解决这个问题。

以下是使用lambda函数的示例代码:

from collections import defaultdict
a = defaultdict(lambda: defaultdict(list))
a["testkey"]["list"] = ["a", "b", "c"]

在这个示例中,我们使用lambda函数作为defaultdict的第一个参数,该lambda函数返回一个新的defaultdict对象,其默认值是一个空列表。然后,我们像之前一样向a中的字典的字典的列表中添加了一个键和值。

通过使用lambda函数,我们可以更加简洁地创建一个字典的字典的列表。这种方式更符合函数式编程的习惯,并且更加直观。因此,我建议使用lambda函数来解决这个问题。

希望上述内容能对你有所帮助,祝你编程愉快!

0
0 Comments

Python中如何使用defaultdict创建一个字典的字典的列表。最初,人们使用lambda函数来实现这个目标,但是有一种更快的方法可以避免使用lambda函数。

在Python中,有一种内置的方法叫做copy,它可以用于创建默认值。通过使用defaultdict的copy方法,我们可以创建一个字典的字典的列表。这种方法的好处是,它不需要执行任何Python字节码或查找任何名称,因此可以更快地生成默认值。

以下是使用defaultdict的copy方法创建字典的字典的列表的示例代码:

from collections import defaultdict
dd = defaultdict(defaultdict(list).copy)

这个方法的行为与使用lambda函数创建字典的字典的列表的方法相同。然而,它通过使用一个在CPython中实现的绑定内置方法来避免使用lambda函数,这意味着默认值的生成不需要执行任何Python字节码或查找任何名称,并且运行速度更快。在CPython 3.5的微基准测试中,当键不存在时,这种方法的开销比使用相同的lambda函数的方法低约5-10%。

实际上,我更喜欢这种方法,是因为我讨厌lambda函数。人们在不恰当的情况下过度使用lambda函数(例如,使用lambda函数的map/filter比等效的listcomp/genexpr更冗长和更慢,但人们仍然出于不可理解的原因继续使用它)。虽然在这种情况下几乎没有什么影响,但我仍然更喜欢避免使用lambda函数。

更新:从Python 3.8开始,这种性能提升消失了,lambda函数更快(在3.8上使用lambda函数减少了约3%的运行时间,在3.9上减少了约7%),通过使用ipython进行简单的微基准测试。如果你想重现我的测试,我测试了以下代码:

from collections import defaultdict
%%timeit
dd = defaultdict(lambda: defaultdict(list))
o = object
dd[o()]

以上代码中,使用`o = object`进行缓存,以最小化查找开销,并且我们可以使用非常便宜的、确保唯一的键来访问(强制自动生成列表),同时不执行其他操作。

3.8版本的性能改进很可能主要是由于引入了LOAD_GLOBAL指令的每个操作码缓存,从而减少了通过完整的字典查找(在内置函数中为两次,对于list来说)来查找defaultdictlist的成本,从而将成本降低了约40%。3.9版本的改进可能(不确定)与CPython的内部优化和更偏爱向量调用代码路径有关,而不是向量调用代码路径(相对而言,defaultdict(list).copy路径使用更多),即使在这些改进之前,defaultdict(list).copy也存在一些效率问题,而lambda函数则没有,为改进提供了一些余地。

总之,使用defaultdict的copy方法来创建字典的字典的列表比使用lambda函数更快。然而,从Python 3.8开始,lambda函数的性能优势消失了。无论如何,这种性能提升都是微不足道的,所以我原来的观点(我讨厌lambda函数因为它们被过度使用)仍然成立,但是现在lambda函数已经变得更快了。

0
0 Comments

问题出现的原因是作者想要创建一个字典的字典的列表,并且希望使用defaultdict来实现。默认情况下,defaultdict只能创建一个字典的字典,而不能创建一个字典的字典的列表。

为了解决这个问题,作者首先尝试使用lambda函数来创建一个defaultdict的defaultdict,如下所示:

defaultdict(lambda: defaultdict(list))

这个方法是有效的,但是作者有一个习惯,就是尽量避免使用lambda函数(因为它们经常被滥用,而总是有更好的选择,比如使用map/filter和lambda的组合总是比直接使用列表推导式/生成器表达式更慢;作者为了避免滥用lambda函数,决定尽量避免使用它们)。因此,作者尝试使用一个空的defaultdict(list)的绑定方法来代替lambda函数,将所有的工作都交给C层处理,这样可以提高运行速度(大约快5-10%):

defaultdict(defaultdict(list).copy)

另外,其他人也对这个解决方法表示了赞同,并提出了自己的想法。作者鼓励其他人将这个解决方法添加到答案中,或者添加自己的答案。

总之,要创建一个字典的字典的列表,可以使用上述的解决方法来使用defaultdict。

0