I am working with DeepDiff. So I have results like:
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}}
Now, I want to take:
list_indexes_added = foo(added)
list_indexes_updated = foo(updated)
and to obtain:
list_indexes_added = [2]
list_index_updated = [(1,2,'age')]
in this way, I can manipulate the list local
and online
and in the future update the online
table.
I am thinking in regexs, but maybe there is other option.
One solution can be regex and custom parsing of the matches.
Another can be using literal_eval
after regex parsing on these strings, if the output format of deepdiff
is consistent
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')]
demo : http://ideone.com/3MhTky
This is what I did:
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
So:
parseRoots({"root[1][2]['age']": {'new_value': 90, 'old_value': 40}})
[[1, 2, 'age']]
Maybe someone can improve it.
So, I'd go with something like this:
import re
def foo(diff):
modded = []
for key in diff.keys():
m = re.search('\[(.+)\]', key)
modded.append(tuple(m.group(1).split('][')))
return modded
It'll read each key, extract only the indices (whether numeric or string), then slice up the string. Since your desired output indicates a tuple, it'll spit the sequence of indices back as one, then return the whole list of index sets (since diff
might have more than one).
This can be golfed down into a one-line list comprehension:
import re
def foo(diff):
return [tuple(re.search('\[(.+)\]', key).group(1).split('][')) for key in diff.keys()]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With