在 Python 中动态编辑字典树
Dynamically edit dict tree in Python
我有一段 PHP 代码正在尝试移植到 Python,我不确定如何在没有引用的情况下工作。
本质上它是一个像树一样工作的配置 class,每个键可以有一个简单的值,或者它自己的一组键和值。 class 的一部分要求能够设置树的一个特定部分,而不必为根键发送一个全新的字典。
{ "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 中甚至有可能吗,还是我应该从头开始重写我的逻辑并放弃一个完美的端口?
您可以按如下方式设置您的设置方法:
_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}}
我尝试了更多,发现我有解决方案,我只是应用不当。
每个字典,即使它是另一个字典的键的一部分,都可以通过引用传递。这意味着如果我更改该字典中的键,它也会在父项中更改。不幸的是,我正在更改引用字典的变量,而不是字典本身。
这非常有效
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]]
我有一段 PHP 代码正在尝试移植到 Python,我不确定如何在没有引用的情况下工作。
本质上它是一个像树一样工作的配置 class,每个键可以有一个简单的值,或者它自己的一组键和值。 class 的一部分要求能够设置树的一个特定部分,而不必为根键发送一个全新的字典。
{ "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 中甚至有可能吗,还是我应该从头开始重写我的逻辑并放弃一个完美的端口?
您可以按如下方式设置您的设置方法:
_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}}
我尝试了更多,发现我有解决方案,我只是应用不当。
每个字典,即使它是另一个字典的键的一部分,都可以通过引用传递。这意味着如果我更改该字典中的键,它也会在父项中更改。不幸的是,我正在更改引用字典的变量,而不是字典本身。
这非常有效
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]]