Python 用另一个字典的值替换嵌套字典的键(其中两个dict的键相等))

Python 用另一个字典的值替换嵌套字典的键(其中两个dict的键相等)),python,dictionary,Python,Dictionary,我有两个dict,dict1和dict2,我想构造新的dict(或操纵dict1),其键值对为(dict2的值:dict1的值[其中dict1的键值和dict2的键值相同]) 预期产出为: dict1 = {'ar': {'ag': 'mon', 'ad': 'tues', 'az': {'ae': {'ai': {'ay': 'wed', 'am': 'yo', 'aq': 'go', 'ab': {'ay': 'to', 'aq': 'so', 'ab': 'mo', 'al': 'kato

我有两个dict,
dict1
dict2
,我想构造新的dict(或操纵
dict1
),其键值对为(dict2的值:
dict1的值
[其中dict1的键值和
dict2的键值相同])

预期产出为:

dict1 = {'ar': {'ag': 'mon', 'ad': 'tues', 'az': {'ae': {'ai': {'ay': 'wed', 'am': 'yo', 'aq': 'go', 'ab': {'ay': 'to', 'aq': 'so', 'ab': 'mo', 'al': 'kato'}}, 'aq': 'talo'}, 'aj': {'key9': {'key24': 'ay', 'ao': 'swan toro', 'am': 'masan.com'}, 'ax': 'qua-la-sa'}, 'at': 'pirat9333', 'ap': {'ak': 'stepg-sdd:sdf', 'au': 'asfd.asf'}, 'av': {'af': 'Tran swa', 'ac': {'am': '1123', 'ah': 'ryan', 'aa': 'http://swan.com'}}, 'aw': {'ai': {'ay': 'mnhfg', 'aq': 'ejs-33', 'ab': {'ay': 'qwqwa-wnnf', 'ab': '213bvn'}}, 'aq': '1234bfh'}}}}
我得到的结果是

output = {'aa': None, 'ac': None, 'ae': None, 'ad': None, 'ag': None, 'af': None, 'ai': None, 'ah': None, 'ak': None, 'aj': None, 'am': None, 'al': None, 'ao': None, 'an': None, 'aq': None, 'ap': None, 'as': None, 'ar': {'key25': {'key5': {'key17': 'talo', 'key9': {'key17': 'go', 'key2': {'key17': 'so', 'key2': 'mo', 'key12': 'kato', 'key24': 'to'}, 'key13': 'yo', 'key24': 'wed'}}, 'key22': {'key17': '1234bfh', 'key9': {'key17': 'ejs-33', 'key2': {'key2': '213bvn', 'key24': 'qwqwa-wnnf'}, 'key24': 'mnhfg'}}, 'key21': {'key3': {'key1': 'http://swan.com', 'key8': 'ryan', 'key13': '1123'}, 'key6': 'Tran swa'}, 'key19': 'pirat9333', 'key16': {'key20': 'asfd.asf', 'key11': 'stepg-sdd:sdf'}, 'key10': {'key23': 'qua-la-sa', 'key9': {'key15': 'swan toro', 'key13': 'masan.com', 'key24': 'ryan'}}}, 'key7': 'mon', 'key4': 'tues'}, 'au': None, 'at': None, 'aw': None, 'av': None, 'ay': None, 'ax': None, 'az': None}
列表作为值的新示例

dict1 = {"key1":{"key3":"value1","key2":"value2","key4":{"key5":"value3","key6":{"key7":"value4","key8":{"key9":"value5","key10":"value6","key55":"value7"}},"key11":{"key12":"value8","key13":"value9"},"key14":[{"key15":"value10","key16":"value11","key17":"value12"},{"key15":"value13","key16":"value14","key17":"value15"}]}}}

dict2 = {"key1":"ab","key2":"bc","key3":"cd","key4":"de","key5":"ef","key6":"fg","key7":"gh","key8":"hi","key9":"ij","key10":"jk","key55":"kl","key11":"lm","key12":"mn","key13":"no","key14":"op","key15":"pq","key16":"qr","key17":"qs"}

如果第一个dict是嵌套的,而第二个dict是平面的,则需要遍历第一个dict,并使用递归函数而不是普通循环。大概是这样的:

def walk(dict1, dict2):
    output = {}
    for key, value in dict1.iteritems():
        if key not in dict2: raise Exception('key {0!r} found in dict1 but not dict2'.format(key))
        if dict2[key] in output: raise Exception('duplicate value {0!r} found in dict2'.format(dict2[key]))
        if isinstance(value, dict):
            output[dict2[key]] = walk(value, dict2)
        else:
            output[dict2[key]] = value
    return output

dict1 = {'key18': {'key7': 'mon', 'key4': 'tues', 'key25': {'key5': {'key9': {'key24': 'wed', 'key13': 'yo', 'key17': 'go', 'key2': {'key24': 'to', 'key17': 'so', 'key2': 'mo', 'key12': 'kato'}}, 'key17': 'talo'}, 'key10': {'key9': {'key24': 'ryan', 'key15': 'swan toro', 'key13': 'masan.com'}, 'key23': 'qua-la-sa'}, 'key19': 'pirat9333', 'key16': {'key11': 'stepg-sdd:sdf', 'key20': 'asfd.asf'}, 'key21': {'key6': 'Tran swa', 'key3': {'key13': '1123', 'key8': 'ryan', 'key1': 'http://swan.com'}}, 'key22': {'key9': {'key24': 'mnhfg', 'key17': 'ejs-33', 'key2': {'key24': 'qwqwa-wnnf', 'key2': '213bvn'}}, 'key17': '1234bfh'}}}}
dict2 = {'key1': 'aa', 'key2': 'ab', 'key3': 'ac', 'key4': 'ad', 'key5': 'ae', 'key6': 'af', 'key7': 'ag', 'key8': 'ah', 'key9': 'ai', 'key10': 'aj', 'key11': 'ak', 'key12': 'al', 'key13': 'am', 'key14': 'an', 'key15': 'ao', 'key16': 'ap', 'key17': 'aq', 'key18': 'ar', 'key2': 'as', 'key19': 'at', 'key20': 'au', 'key21': 'av', 'key22': 'aw', 'key23': 'ax', 'key24': 'ay', 'key25': 'az'}
output = walk(dict1, dict2)
print output
结果输出:

目前,人们的一些收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集,作为作为作为作为作为收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集收集{'aq':'ejs-33','ay':'mnhfg','as':{'ay':'qwqwa wnnf','as':'213bvn'}}},'av':{'ac':{'aa':'http://swan.com“,”啊“:”瑞安“,”am“:”1123“,”阿飞“:”特兰斯瓦“},,”广告“:”周二“,”阿格“:”周一“}

我添加了几个您可能想要处理的异常。第一个异常处理
dict2
不包含在
dict1
中找到的键的情况。第二个异常处理
dict2
中两个相同值的情况,这将导致它们在
输出中写入同一个键我们丢失了一些数据

另外,我不确定您是否知道,但是您的
dict2
声明包含两个
'key2'
实例。即使这不是问题(很可能是),您也应该处理它

另外,如果你想遍历列表,你需要两种遍历方法:一种用于dicts,另一种用于list,因为它们的逻辑明显不同

def walk(dict1, dict2):
    output = {}
    for key, value in dict1.iteritems():
        if key not in dict2: raise Exception('key {0!r} found in dict1 but not dict2'.format(key))
        if dict2[key] in output: raise Exception('duplicate value {0!r} found in dict2'.format(dict2[key]))
        if isinstance(value, dict):
            output[dict2[key]] = walk(value, dict2)
        elif isinstance(value, list):
            output[dict2[key]] = walk_list(value, dict2)
        else:
            output[dict2[key]] = value
    return output

def walk_list(sublist, dict2):
    output = []
    for value in sublist:
        if isinstance(value, dict):
            output.append(walk(value, dict2))
        elif isinstance(value, list):
            output.append(walk_list(value, dict2))
        else:
            output.append(value)
    return output

虽然类型相同,但你有两种不同的东西:一种是
dict
,另一种是
dict
dict
。不是那么简单的
dict
理解可以解决它的问题,如果不是629个字符宽,那么示例代码读起来就更好了。换行,只是一个建议……非常感谢你太好了。这个输入非常有用,但对于我的输入,我得到了一些键错误,但无论如何,您现在已经让我走上了正确的道路:-)如何添加另一个条件isinstance(value,list):在这段代码中,(键的值可能是一个包含多个键值对的列表)?感谢您的良好解释。上述代码的问题是,walk_list函数使用两个参数调用,而它需要一个参数。子列表是什么?您能测试代码吗?我应该提供输入dict供您测试吗?我提供了新的输入示例,请尝试使用此输入执行您的代码,我是gettt正在打包错误“ValueError:太多值无法解包”。@Ritzor这是因为代码用于键/值对列表。如果是简单列表,代码会变得简单得多。
def walk(dict1, dict2):
    output = {}
    for key, value in dict1.iteritems():
        if key not in dict2: raise Exception('key {0!r} found in dict1 but not dict2'.format(key))
        if dict2[key] in output: raise Exception('duplicate value {0!r} found in dict2'.format(dict2[key]))
        if isinstance(value, dict):
            output[dict2[key]] = walk(value, dict2)
        elif isinstance(value, list):
            output[dict2[key]] = walk_list(value, dict2)
        else:
            output[dict2[key]] = value
    return output

def walk_list(sublist, dict2):
    output = []
    for value in sublist:
        if isinstance(value, dict):
            output.append(walk(value, dict2))
        elif isinstance(value, list):
            output.append(walk_list(value, dict2))
        else:
            output.append(value)
    return output