如何将派生的递归数据类型转换为基本数据类型?

时间:2010-12-14 18:50:48

标签: python oop

我有一个名为nesteddict的类,派生自collections.defaultdict,它包含一组嵌套的字典:

import collections

class nesteddict(collections.defaultdict):
    """Nested dictionary structure.

    Based on Stack Overflow question 635483
    """
    def __init__(self):
        collections.defaultdict.__init__(self, nesteddict)
        self.locked = False

我希望能够执行一个操作,将所有nesteddict对象转换为python-native dict对象。

执行此操作的一种方法是使用方法:

def todict(self):
    for (key,val) in self.iteritems():
        if isinstance(val,nesteddict):
            val.todict()
            self[key] = dict(val)
    self = dict(self)

使用dict类型替换所有内部映射对象是成功的,但是方法中的最后一个语句显然不起作用。

以下是一个例子:

In [93]: a = pyutils.nesteddict()

In [94]: a[1][1] = 'a'

In [95]: a[1][2] = 'b'

In [96]: a[2][1] = 'c'

In [97]: a[2][2] = 'd'

In [98]: print a
defaultdict(<class 'pyutils.nesteddict'>, {1: defaultdict(<class 'pyutils.nesteddict'>, {1: 'a', 2: 'b'}), 2: defaultdict(<class 'pyutils.nesteddict'>, {1: 'c', 2: 'd'})})

In [99]: a.todict()

In [100]: print a
defaultdict(<class 'pyutils.nesteddict'>, {1: {1: 'a', 2: 'b'}, 2: {1: 'c', 2: 'd'}})

有没有办法在python中执行此操作?有一个方法将其对象转换为另一种类型?如果没有,那么这是一个很好的选择。请注意,实际中的数据类型可能很大,因此最好不要只复制然后返回它。

谢谢!
URI

4 个答案:

答案 0 :(得分:5)

将它作为一个免费功能,当你在它时,考虑一个更实用的风格方法:

def undefaulted(x):
  return dict(
    (k, undefaulted(v))
    for (k, v) in x.iteritems()
  ) if isinstance(x, nesteddict) else x

a = undefaulted(a)

答案 1 :(得分:3)

我刚刚使用嵌套的defaultdicts来解决这个问题。我的解决方案:

def dictify(d):
    return {k:dictify(v) for k,v in d.items()} if \
        isinstance(d,nesteddict) else d

最好使用{}而不是dict()因为调用了 dict()的构造函数限制了关键字参数的数量 至255.请参阅:What is a maximum number of arguments in a Python function?

答案 2 :(得分:1)

dict(a)将为您提供来自defaultdict的任何对象的默认字典。也就是说,假设您没有覆盖所需的特殊方法。

答案 3 :(得分:0)

我在代码中注意到的第一件事是您正在修改(或尝试)self变量。该变量只是指向您班级的当前实例。如果重新分配它,则只是将其指向另一个值,但self指向的先前值保持不变。这就是Python的工作原理。

所以,你应该只是在你的方法中返回转换的结果......就像这样:

def anothertodict(self):
    stuff = dict(self)
    for (key,val) in stuff.iteritems():
        if isinstance(val,nesteddict):
            stuff[key] = val.anothertodict()
    return stuff

这样,如果你做了:print a.anothertodict(),你就会得到你期望得到的东西。

PS:你为什么需要从defaultdict转换为dict?