4

假设我想在 Python 中使用类似 PERL 的自动生存,即:

>>> d = Autovivifier()
>>> d = ['nested']['key']['value']=10
>>> d
{'nested': {'key': {'value': 10}}}

有几种主要的方法可以做到这一点:

  1. 使用递归默认字典
  2. 使用__missing__钩子返回嵌套结构

好的——简单。

现在假设我想从缺少键的字典中返回默认值。再一次,有几种方法可以做到这一点:

  1. 对于非嵌套路径,您可以使用__missing__钩子
  2. try/except 阻止包装对可能丢失的密钥路径的访问
  3. 使用{}.get(key, default) (不容易使用嵌套字典)即,没有版本autoviv.get(['nested']['key']['no key of this value'], default)

这两个目标似乎存在不可调和的冲突(基于我在过去几个小时试图解决这个问题。)

这是问题:

假设我想要一个 Autovivifying dict 1) 创建嵌套结构d['arbitrary']['nested']['path'];AND 2) 从不存在的任意嵌套返回默认值,而不将其包装在 try/except 中?

以下是问题:

  1. 的调用d['nested']['key']['no key of this value'] 等效于 (d['nested'])['key']['no key of this value']__getitem__如果不返回 ALSO 覆盖的对象,则覆盖不起作用__getitem__
  2. 如果您测试该路径是否存在,那么这两种创建 Autovivifier 的方法都会创建一个 dict 条目。即,if d['p1']['sp2']['etc.']如果您只是使用if.

如何在 Python 中提供一个 dict,它将:

  1. 创建类型的访问路径d['p1']['p2'][etc]=val(Autovivication);
  2. 如果您测试是否存在,请不要创建相同的路径;
  3. 返回一个默认值(如{}.get(key, default))而不包含在 try/except 中
  4. 我不需要完整的 dict 操作集。真的只有d=['nested']['key']['value']=vald['nested']['key']['no key of this value']等于一个默认值。我希望测试d['nested']['key']['no key of this value']不会创建它,但会接受。

?

4

3 回答 3

4

要创建字典的递归树,请使用defaultdict以下技巧:

from collections import defaultdict

tree = lambda: defaultdict(tree)

然后你可以用x = tree().

以上来自@BrenBarn—— defaultdict的defaultdict,嵌套

于 2014-06-30T04:25:38.193 回答
2

不要这样做。只需编写一个具有您想要的操作的类就可以更容易地解决它,即使在 Perl 中它也不是一个普遍评价的特性。

但是,使用自定义 autoviv 类是可能的。你需要一个__getitem__返回一个空的 autoviv 字典但不存储它的。新的 autoviv dict 会记住 autoviv dict 和创建它的键,然后只有在其中存储“真实”值时才将自己插入其父级。

由于空 dict 测试为假,因此您可以测试是否存在 Perl 样式,而无需实际创建中间 dicts。

但我不会把代码写出来,因为我很确定这是一个糟糕的主意。

于 2014-06-30T04:37:06.660 回答
1

虽然它与 Python 中的字典协议不完全匹配,但您可以通过实现自己的使用可变getitem参数的自动激活字典来获得合理的结果。像(2.x)这样的东西:

class ExampleVivifier(object):
    """ Small example class to show how to use varargs in __getitem__. """

    def __getitem__(self, *args):
        print args

示例用法是:

>>> v = ExampleVivifier()
>>> v["nested", "dictionary", "path"]
(('nested', 'dictionary', 'path'),)

您可以填写空白以查看如何在此处实现所需的行为。

于 2014-06-30T13:57:45.687 回答