解析 DeepDiff 结果
Parsing DeepDiff result
我正在与 DeepDiff 合作。所以我得到的结果如下:
local = [{1: {'age': 50, 'name': 'foo'}}, {2: {'age': 90, 'name': 'bar'}}, {3: {'age': 60, 'name': 'foobar'}}]
online = [{1: {'age': 50, 'name': 'foo'}}, {2: {'age': 40, 'name': 'bar'}}]
ddiff = DeepDiff(local, online)
added, updated = ddiff['iterable_item_added'], ddiff['values_changed']
added = {'root[2]': {3: {'age': 60, 'name': 'foobar'}}}
updated = {"root[1][2]['age']": {'new_value': 90, 'old_value': 40}}
现在,我想拿:
list_indexes_added = foo(added)
list_indexes_updated = foo(updated)
并获得:
list_indexes_added = [2]
list_index_updated = [(1,2,'age')]
通过这种方式,我可以操作列表 local
和 online
并在将来更新 online
table。
我在考虑正则表达式,但也许还有其他选择。
所以,我会选择这样的东西:
import re
def foo(diff):
modded = []
for key in diff.keys():
m = re.search('\[(.+)\]', key)
modded.append(tuple(m.group(1).split('][')))
return modded
它将读取每个键,仅提取索引(无论是数字还是字符串),然后将字符串切分。由于您想要的输出表示一个元组,它会将索引序列作为一个吐出,然后 return 整个索引集列表(因为 diff
可能不止一个)。
这可以简化为单行列表理解:
import re
def foo(diff):
return [tuple(re.search('\[(.+)\]', key).group(1).split('][')) for key in diff.keys()]
一个解决方案可以是匹配的正则表达式和自定义解析。
另一种可以在对这些字符串进行正则表达式解析后使用literal_eval
,如果deepdiff
的输出格式一致
from ast import literal_eval
import re
def str_diff_parse(str_diff):
return [tuple(literal_eval(y) for y in re.findall(r"\[('?\w+'?)\]", x)) for x in str_diff]
added = {'root[2]': {3: {'age': 60, 'name': 'foobar'}}}
updated = {"root[1][2]['age']": {'new_value': 90, 'old_value': 40}}
list_indexes_added = str_diff_parse(added)
list_indexes_updated = str_diff_parse(updated)
print(list_indexes_added)
print(list_indexes_updated)
# prints
#[(2,)]
#[(1, 2, 'age')]
- 也会推荐 dictdiffer 模块,它 returns diff 作为一个消耗品 python diff 对象可以修补到原始字典以获得更新的字典,反之亦然。
这是我做的:
def getFromSquareBrackets(s):
return re.findall(r"\['?([A-Za-z0-9_]+)'?\]", s)
def auxparse(e):
try:
e = int(e)
except:
pass
return e
def castInts(l):
return list((map(auxparse, l)))
def parseRoots(dics):
"""
Returns pos id for list.
Because we have formmatted [{id:{dic}}, {id:{dic}}]
"""
values = []
for d in dics:
values.append(castInts(getFromSquareBrackets(d)))
return values
所以:
parseRoots({"root[1][2]['age']": {'new_value': 90, 'old_value': 40}})
[[1, 2, 'age']]
也许有人可以改进它。
我正在与 DeepDiff 合作。所以我得到的结果如下:
local = [{1: {'age': 50, 'name': 'foo'}}, {2: {'age': 90, 'name': 'bar'}}, {3: {'age': 60, 'name': 'foobar'}}]
online = [{1: {'age': 50, 'name': 'foo'}}, {2: {'age': 40, 'name': 'bar'}}]
ddiff = DeepDiff(local, online)
added, updated = ddiff['iterable_item_added'], ddiff['values_changed']
added = {'root[2]': {3: {'age': 60, 'name': 'foobar'}}}
updated = {"root[1][2]['age']": {'new_value': 90, 'old_value': 40}}
现在,我想拿:
list_indexes_added = foo(added)
list_indexes_updated = foo(updated)
并获得:
list_indexes_added = [2]
list_index_updated = [(1,2,'age')]
通过这种方式,我可以操作列表 local
和 online
并在将来更新 online
table。
我在考虑正则表达式,但也许还有其他选择。
所以,我会选择这样的东西:
import re
def foo(diff):
modded = []
for key in diff.keys():
m = re.search('\[(.+)\]', key)
modded.append(tuple(m.group(1).split('][')))
return modded
它将读取每个键,仅提取索引(无论是数字还是字符串),然后将字符串切分。由于您想要的输出表示一个元组,它会将索引序列作为一个吐出,然后 return 整个索引集列表(因为 diff
可能不止一个)。
这可以简化为单行列表理解:
import re
def foo(diff):
return [tuple(re.search('\[(.+)\]', key).group(1).split('][')) for key in diff.keys()]
一个解决方案可以是匹配的正则表达式和自定义解析。
另一种可以在对这些字符串进行正则表达式解析后使用
literal_eval
,如果deepdiff
的输出格式一致from ast import literal_eval import re def str_diff_parse(str_diff): return [tuple(literal_eval(y) for y in re.findall(r"\[('?\w+'?)\]", x)) for x in str_diff] added = {'root[2]': {3: {'age': 60, 'name': 'foobar'}}} updated = {"root[1][2]['age']": {'new_value': 90, 'old_value': 40}} list_indexes_added = str_diff_parse(added) list_indexes_updated = str_diff_parse(updated) print(list_indexes_added) print(list_indexes_updated) # prints #[(2,)] #[(1, 2, 'age')]
- 也会推荐 dictdiffer 模块,它 returns diff 作为一个消耗品 python diff 对象可以修补到原始字典以获得更新的字典,反之亦然。
这是我做的:
def getFromSquareBrackets(s):
return re.findall(r"\['?([A-Za-z0-9_]+)'?\]", s)
def auxparse(e):
try:
e = int(e)
except:
pass
return e
def castInts(l):
return list((map(auxparse, l)))
def parseRoots(dics):
"""
Returns pos id for list.
Because we have formmatted [{id:{dic}}, {id:{dic}}]
"""
values = []
for d in dics:
values.append(castInts(getFromSquareBrackets(d)))
return values
所以:
parseRoots({"root[1][2]['age']": {'new_value': 90, 'old_value': 40}})
[[1, 2, 'age']]
也许有人可以改进它。