在Python中动态编辑dict树

时间:2015-02-23 22:54:50

标签: php python reference tree

我有一段PHP代码,我正在尝试移植到Python,我不确定如何在没有引用的情况下工作。

本质上,它是一个像树一样工作的配置类,每个键都可以有一个简单的值,或者它自己的一组键和值。该类的一部分要求能够设置树的一个特定部分,而不必为根密钥发送整个新的字典。

{ "caching": { "enabled": true }}

例如,以上可能是一个简单的配置。调用以下代码会将true更改为false

Config.set('caching:enabled', false);

为了在PHP中实现这一点,我使用了引用

class Config
{
    private static $aValues;

    public static function set($key, $value)
    {
        if(strpos($key, ':')) {
            $aKeys  = explode(':', $key);
            $iCount = count($aKeys);
        } else {
            $aKeys  = array($key);
            $iCount = 1
        }

        $mData  = &self::$aValues
        for($i = 0; $i < $iCount; ++$i)
        {
            if(!isset($mData[$aKeys[$i])) {
                $mData[$aKeys[$i]]  = array();
            }

            $mData  = &$mData[$aKeys[$i]];

            if($i == ($iCount - 1)) {
                $mData  = $value;
            }
        }
    }
}

但是如果我尝试在Python中做类似的事情

_dmValues = dict()

def set(key, value):
    global _dmValues

    if key.find(':'):
        aKey    = key.split(':')
        iCount  = len(key)
    else:
        aKey    = (key,)
        iCount  = 1

    mData   = _dmValues;
    for i in range(0, iCount):
        if key[i] not in mData.keys():
            mData[key[i]]   = dict()

        mData   = mData[key[i]]

        if i == (iCount - 1):
            mData   = value

它没有用,mData是正确的值,但是因为我写了它,它不再是一个参考。

我该怎么做呢?它甚至可以在Python中使用,还是我应该从头开始重写我的逻辑并放弃一个完美的端口?

2 个答案:

答案 0 :(得分:0)

您可以按如下方式设置set方法:

_dmValues = { "caching": { "enabled": True }}

def set(key, value):
    global _dmValues

    key1,key2    = key.split(':')    

    mData   = _dmValues;

    if key1 in mData:
        if key2 in mData[key1]:
            mData[key1][key2] = value


set('caching:enabled', False)

print(_dmValues)  # {'caching': {'enabled': False}}    

尽管可能最好删除全局值并将对dict的引用作为参数传递:

def set(mData, key, value):       
    key1,key2    = key.split(':')           
    if key1 in mData:
        if key2 in mData[key1]:
            mData[key1][key2] = value


set(_dmValues, 'caching:enabled', False)

print(_dmValues) # {'caching': {'enabled': False}}   

答案 1 :(得分:0)

我更多地玩弄它并意识到我有解决方案,我只是不恰当地应用它。

每个字典,即使它是另一个字典的键的一部分,也可以通过引用传递。这意味着如果我更改该字典中的某个键,它也将在父级中更改。不幸的是,我正在更改作为字典引用的变量,而不是字典本身。

这完美无缺

mData = _dm_Values
for i in range(0, iCount):
    if i == (iCount - 1):
        mData[key[i]] = value
    else:
        if key[i] not in mData.keys():
            mData[key[i]] = dict()
        mData = mData[key[i]]