鉴于这两个方面:
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
值的键,但无论出于何种原因,我的代码到目前为止都会生成一个空的字典{}
。
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'}}
作为一个好的起点。无论如何,我想这个任务存在更多干净的解决方案然后正则表达式,所以欢迎任何提示!
答案 0 :(得分: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'}]}}