映射嵌套数据结构中的字符串

时间:2017-05-17 10:48:53

标签: python list dictionary recursion

映射由列表和词典组成的两个数据结构。 data的映射应递归地应用于payload结构。

这些是我的输入

data = {
    'a': 'Apple',
    'b': 'Ball',
    'c': 'Cat',
    'd': 'Dog',
    'e': 'Egg',
    'f': 'Fish',
    'g': 'Goat',
    'h': 'House',
    'i': 'Ice-Cream',
    'j': 'Jaguar',
    'k': 'Key',
    'l': 'Lock',
    'm': 'Map'
}

payload = {
    'PI': [
        {
            'one': 'a',
            'two': 'b',
            'three': 'c',
            'four': {
                'five': 'd',
                'six': 'e',
                'seven': 'f',
                'eight': 'g'
            }
        }, {
            'nine': 'h',
            'ten': 'i',
            'eleven': 'j',
            'twelve': 'k'
        }
    ]
}

预期产出:

payload = {
    'PI': [
        {
            'one': 'Apple',
            'two': 'Ball',
            'three': 'Cat',
            'four': {
                'five': 'Dog',
                'six': 'Egg',
                'seven': 'Fish',
                'eight': 'Goat'
            }
        }, {
            'nine': 'House',
            'ten': 'Ice-Cream',
            'eleven': 'Jaguar',
            'twelve': 'Key'
        }
    ]
}

这是我尝试创建映射但它无法正常工作

def mapping(payload):
    for k,v in payload.items():
        if(isinstance(v,dict)):
            mapping(v)
        elif(isinstance(v,list)):
            for item in v:
                mapping(item)
        else:
            try:
                v = data[v]
            except KeyError:
                pass
        return payload

我得到了这个:

{
    'PI': [
        {
            'four': {
                'eight': 'g', 
                'five': 'd', 
                'seven': 'f', 
                'six': 'e'
            },
            'one': 'a',
            'three': 'c',
            'two': 'b'
        },
        {
            'eleven': 'j',
            'nine': 'h',
            'ten': 'i',
            'twelve': 'k'
        }
    ]
}

什么都没有被替换。

1 个答案:

答案 0 :(得分:0)

你确实可以使用递归;递归列表值和字典元素,并直接映射其他所有内容。不要忘记返回结果;递归函数创建新的词典和列表:

def replace_strings(value, mapping):
    if isinstance(value, list):
        return [replace_strings(v, mapping) for v in value]
    if isinstance(value, dict):
        return {replace_strings(k, mapping): replace_strings(v, mapping)
                for k, v in value.items()}
    return mapping.get(value, value)

演示:

>>> pprint(replace_strings(payload, data))
{'PI': [{'four': {'eight': 'Goat',
                  'five': 'Dog',
                  'seven': 'Fish',
                  'six': 'Egg'},
         'one': 'Apple',
         'three': 'Cat',
         'two': 'Ball'},
        {'eleven': 'Jaguar',
         'nine': 'House',
         'ten': 'Ice-Cream',
         'twelve': 'Key'}]}

您的代码有几个问题:

  • 您忽略了任何递归调用的返回值。
  • 您返回原始输入,未经更改。