I have a python dictionary like below:
j = {'a':'b',
'c':'d',
'e':'f',
'd':'g',
'h':'i',
'b':'j',
'g':'k'}
The key is the old_id and the value is the new_id. A few of the values are again repeated as keys, as and when the new_id is updated again. I want to update the dictionary such that the keys have the latest values.
I want my new dictionary to look like this:
j = {'a':'j',
'c':'k',
'e':'f',
'd':'k',
'h':'i',
'b':'j',
'g':'k'
}
PS: Please note this is just sample data. I have only the initial dictionary available to me.
CodePudding user response:
If you don't have to do it in-place (i.e. your replacements should be counted earlier while iterating the dict (be aware that ordered dicts by default aren't a thing before cpython 3.6)), you can do something like:
j = {'a':'b',
'c':'d',
'e':'f',
'd':'g',
'h':'i',
'b':'j',
'g':'k'}
converted = {}
for d_key in j:
current = d_key
while current in j:
current = j[current]
converted[d_key] = current
print(converted)
The current
part tracks the replacement until exhausting (when the new key is no longer in the table.
If you want to do it inplace, replace converted
with j
- you should be fine as long as you only work with the keys and don't add any new keys (modifying a structure while iterating over it is usually no-no).
CodePudding user response:
Just do a loop and keep checking if value present as key in dictionary. if it is not then update the value with that value otherwise go with the loop again
j = {'a':'b',
'c':'d',
'e':'f',
'd':'g',
'h':'i',
'b':'j',
'g':'k'}
for k, v in j.items():
while v in j:
v = j[v]
j[k]= v
print(j)
output
{'a': 'j',
'c': 'k',
'e': 'f',
'd': 'k',
'h': 'i',
'b': 'j',
'g': 'k'
}
CodePudding user response:
for k in j.keys():
for k2 in j.keys():
if j[k] == k2:
j[k] = j[k2]
So you go through all keys (k2) and test if any value matches with k if they do you replace them. So O(n²), not really efficient. But it works.
CodePudding user response:
IIUC, You need DFS algorithm
and you can do this with recursive approach
like below:
dct = {'a':'b', 'c':'d', 'e':'f', 'd':'g', 'h':'i', 'b':'j', 'g':'k'}
def new_dct(dct):
def dfs(k):
if k in dct:
return dfs(dct[k])
return k
n_dct = {}
for k,v in dct.items():
n_dct[k] = dfs(v)
return n_dct
print(new_dct(dct))
Output:
{'a': 'j', 'c': 'k', 'e': 'f', 'd': 'k', 'h': 'i', 'b': 'j', 'g': 'k'}