1

鉴于这两个字典:

empty = {'151': {'1': 'empty', '0': 'empty', '2': '2.30'}}
full = {'151': {'1': 3.4, '0': 3.6, '2': 2}}

首先,我想检查empty.keys() == full.keys()它是否成立,我想用字典empty中的相应值替换这些值。full它应该导致:

not_empty = {'151': {'1': '3.4', '0': '3.6', '2': '2.30'}}

到目前为止我的解决方案:我认为我会empty使用正则表达式来识别所有带有值的键,但无论出于何种原因,到目前为止我的代码都会产生一个空的 dict {}

import re 
find_empty = re.findall("'(\d)':\s'empty'", str(empty))[0]

if empty.keys() == full.keys():
    k = empty.values()[0].keys()
    v = empty.values()[0].values()
    print {k:v for k,v in empty.values()[0].iteritems()\
                   if empty.values()[0][find_empty] != 'empty'}

我希望它可以输出{'151': {'2': '2.30'}}一个好的起点。无论如何,我想这个任务存在比正则表达式更干净的解决方案,所以欢迎任何提示!

4

1 回答 1

3

正则表达式不是这项工作的正确工具。我建议采用如下递归方法。

empty = {'151': {'1': 'empty', '0': 'empty', '2': '2.30'}}
full = {'151': {'1': 3.4, '0': 3.6, '2': 2}}

def repl(a, b):
    clean = {}
    for k, v in a.items():
        # This is the case where we want to replace what we have in b if we have something.  Just in case, use the dict.get method and provide a default.
        if v == 'empty': 
            clean[k] = b.get(k, 'Not there')
        # If the value is another dict, then call this function with the value, and put the return as the value for our current key
        elif isinstance(v, dict):
            v_clean = repl(v, b.get(k, {}))
            clean[k] = v_clean
        # The value isn't equal to 'empty', and it isn't another dict, so just keep the current value.
        else:
            clean[k] = v
    # Finally, return the cleaned up dictionary.
    return clean

print repl(empty, full)

输出

{'151': {'1': 3.4, '0': 3.6, '2': '2.30'}}

编辑 我不确定这是否能解决你所有的情况,但无论如何它可能值得一看。

empty = {'151': {'1': 'empty', '0': 'empty', '2': '2.30', '8': ['empty', 'empty', 5, {"foo2": "bar2", "1": "empty"}]}}
full = {'151': {'1': 3.4, '0': 3.6, '2': 2, '8': ['foo', 'bar', 'baz', {"foo3": "bar3", "1": "2"}]}}

def repl(a, b):
    if isinstance(a, dict) and isinstance(b, dict):
        clean = {}
        for k, v in a.items():
            # This is the case where we want to replace what we have in b if we have something.  Just in case, use the dict.get method and provide a default.
            if v == 'empty':
                clean[k] = b.get(k, 'Not there')
            # If the value is another dict, then call this function with the value, and put the return as the value for our current key
            elif isinstance(v, dict):
                v_clean = repl(v, b.get(k, {}))
                clean[k] = v_clean
            # The value isn't equal to 'empty', and it isn't another dict, so just keep the current value.
            elif isinstance(v, list):
                v_clean = repl(v, b.get(k, []))
                clean[k] = v_clean
            else:
                clean[k] = v
        # Finally, return the cleaned up dictionary.
    elif isinstance(a, list) and isinstance(b, list):
        clean = []
        for item_a, item_b in zip(a, b):
            if item_a == 'empty':
                clean.append(item_b)
            elif isinstance(item_a, dict):
                clean_a = repl(item_a, item_b)
                clean.append(clean_a)
            else:
                clean.append(item_a)
    return clean

print repl(empty, full)

输出

{'151': {'1': 3.4, '0': 3.6, '2': '2.30', '8': ['foo', 'bar', 5, {'1': '2', 'foo2': 'bar2'}]}}
于 2013-07-05T05:30:56.453 回答