I have a dictionary where I want to compare and print out the difference between the dicts.
old_state = {
'https://github.com/search?q=i love python': {'title': 'i love python', 'repo_count': '517'},
'https://github.com/search?q=python 3': {'title': 'python 3', 'repo_count': '101K'},
'https://github.com/search?q=world': {'title': 'world', 'repo_count': '1M'},
'https://github.com/search?q=hello world': {'title': 'hello world', 'repo_count': '1M'}
}
new_state = {
'https://github.com/search?q=python 3': {'title': 'python 3', 'repo_count': '102K'},
'https://github.com/search?q=world': {'title': 'world', 'repo_count': '1M'},
'https://github.com/search?q=hello world': {'title': 'hello world', 'repo_count': '1M'},
'https://github.com/search?q=i love python': {'title': 'i love python', 'repo_count': '517'}
}
This is the dict that I have done and so far I managed to solve my issue without using the key and value but to just have a value something like this:
old_state = {'title': 'i love python', 'repo_count': '517'}
new_state = {'title': 'python 3', 'repo_count': '102K'}
if old_state['title'] != new_state['title']:
print('new change in title')
if old_state['repo_count'] != new_state['repo_count']:
print('new change in repo count')
The output is the one that I wish to have when it comes to a bigger dictionary with nested dicts of dict(key-value). However my knowledge is not that great yet to know how to do it with bigger dictionaries when it comes to having key-value. My question is, is it possible to do it with the dictionary that I have stated in the beginning and if yes, how am I able to have an output of what I have shown before?
CodePudding user response:
I would proceed by creating a Dataframe:
import pandas as pd
df = pd.merge(
pd.DataFrame(old_state).T,
pd.DataFrame(new_state).T,
left_index=True, right_index=True,
suffixes=["_old", "_new"]
)
now you can check the changes with:
if (df.title_old!=df.title_new).any():
print('new change in title')
if (df.repo_count_old!=df.repo_count_new).any():
print('new change in repo count')
Thanks to the Dataframe you can also print the information of the change. For example, in your case:
df.loc[df.repo_count_old!=df.repo_count_new, ["repo_count_old", "repo_count_new"]]
CodePudding user response:
You can cycle using the keys()
function
for x in new_state.keys():
if old_state[x]['title'] != new_state[x]['title']:
print('new change in title')
if old_state[x]['repo_count'] != new_state[x]['repo_count']:
print('new change in repo count')
Basically keys
retrieve all the keys of your dictionary and you can use them to cycle over the nested dictionary
Instead of using new_state.keys()
you can use old_state.keys()
or the dictionary with the smaller number of keys (if you took the bigger one it trows error because it can't find some keys)
Because the code above trows error if keys are different you can create a new key set with the intersection of the keys that are in common with both dictionary using set(old_state.keys()).intersection(new_state.keys())
So the cycle will be
for x in set(old_state.keys()).intersection(new_state.keys())
CodePudding user response:
I found the common keys. Then I compared them according to the value value and printed the ones with different values. That's the main logic. You can manipulate the code however you want.
old_keys = old_state.keys()
new_keys = new_state.keys()
intersect_keys = set(old_keys).intersection(set(new_keys))
for i in intersect_keys:
if old_state[i] != new_state[i]:
print(f"{i} for old_state = {old_state[i]} and {i} for new_state={new_state[i]}")
else:
pass
CodePudding user response:
I'd iterate over all keys and if the change is in a dict, do it recursively, so you can see both the URL and the changed keys:
def diff(old, new):
for key in new.keys():
try:
if old[key] != new[key]:
print(f'New change in {key}')
if type(new[key]) == dict:
diff(old[key], new[key])
except KeyError:
print(f'New key added: {key}')
for key in old.keys():
try:
new[key]
except KeyError:
print(f'Key removed: {key}')
diff(old_state, new_state)
The try and except blocks handle the case if some keys are added or removed.
So it has an output like this:
New key added: https://github.com/search?q=new
New change in https://github.com/search?q=python 3
New change in repo_count
Key removed: https://github.com/search?q=old