Python - 追加到嵌套在 dict 子类中的列表

Posted

技术标签:

【中文标题】Python - 追加到嵌套在 dict 子类中的列表【英文标题】:Python - Append to list nested in dict subclass 【发布时间】:2012-10-09 02:46:09 【问题描述】:

我有一个 dict 子类,它的工作是在嵌套 dict 键不存在时动态添加它,如果调用 append 则执行列表追加:

class PowerDict(dict):
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value
    def append(self,item):
        if type(self) != list:
            self = list()
            self.append(item)

所以

a = PowerDict()
a['1']['2'] = 3

产生输出:

a = '1': '2': 3

但是,有时我需要做这样的事情:

b = PowerDict()
b['1']['2'].append(3)
b['1']['2'].append(4)

应该产生输出:

b = '1': '2': [3, 4]

但上面的代码会产生输出:

'1': '2': 

我错过了什么?

【问题讨论】:

你不能说self=list() ...您需要将键设置为等于列表... self 是一个字典 确实,self = list() 只是重新绑定了变量self 您是否附加到多索引格式?我发现一个由元组索引的字典更优雅:a[1,2]=3 【参考方案1】:

您的 append() 方法永远不会起作用。通过执行self = list(),您只是将名称self 重新分配到一个新列表,然后将其丢弃。

而且我不明白您要做什么 - 从 getitem 开始,如果缺少某些内容,您正在即时创建新字典......您将如何混合列表行为?

【讨论】:

【参考方案2】:

您的一个问题是重新分配自我,但事实并非如此。尝试在 append 命令中打印出 self 的值,可以看到另一个问题:循环进入了无限递归。这是因为您在 append 命令中调用 powerDict 上的 append 命令!

这应该可以解决您的问题,而无需重新编写 append 命令,但我强烈建议您还是重新编写它以避免上述问题:

b['1']['2']= [3]
b['1']['2'].append(4)

【讨论】:

【参考方案3】:
class PowerDict(dict):
    # http://***.com/a/3405143/190597 (gnibbler)
    def __init__(self, parent = None, key = None):
        self.parent = parent
        self.key = key
    def __missing__(self, key):
        self[key] = PowerDict(self, key)
        return self[key]
    def append(self, item):
        self.parent[self.key] = [item]
    def __setitem__(self, key, val):
        dict.__setitem__(self, key, val)
        try:
            val.parent = self
            val.key = key
        except AttributeError:
            pass

a = PowerDict()
a['1']['2'] = 3
print(a)

b = PowerDict()
b['1']['2'].append(3)
b['1']['2'].append(4)
print(b)

a['1']['2'] = b
a['1']['2'].append(5)
print(a['1']['2'])

产量

'1': '2': 3
'1': '2': [3, 4]
[5]

【讨论】:

@unutbu 我强烈不同意这种想法。当“遍历”这样的“powerdict”时,您永远不会知道您将使用哪种类型(除非您为此使用“isinstance”,这通常被认为不是一个好习惯)。你怎么知道如何处理从字典中获取的值? 不喜欢PowerDict 是有原因的——尤其是__setitem__ 的潜在错误。但是遍历不是PowerDict 独有的问题。您的反对同样适用于普通嵌套字典:'1': '2': [3, 4], ...。我想在这篇文章中展示的是,用所需的语法糖实现一个对象是可能的。可取性的问题取决于上下文。这只是用于学习还是用于生产代码?由于OP没有说明,我没有建议。 @unutbu 但发帖者可能经验不足,需要关于做什么和不做什么的建议,而不仅仅是一个可能是坏主意的工作实施。

以上是关于Python - 追加到嵌套在 dict 子类中的列表的主要内容,如果未能解决你的问题,请参考以下文章

将嵌套dict的值赋给python中的列表

AWS Glue:如何将嵌套的 Hive 结构扩展到 Dict?

Pythonic方法编码嵌套在dict中的列表项

Python对字典列表进行去重追加

Python - 嵌套字典中的最大值键,泛化

Python:展平多个嵌套的字典并追加