I am working on a question that requires to point out the problem in a function that determines whether a dictionary is invertible (for every value appearing in the dictionary, there is only one key that maps to that value) or not. The question is below:
def is_invertible(adict):
inv_dict = make_inv_dict(adict)
return adict == inv_dict
def make_inv_dict(adict):
if len(adict) > 0:
key, val = adict.popitem()
adict = make_inv_dict(adict)
if val not in adict.values():
adict[key] = val
return adict
else:
return {}
Currently, this returns False
for {'a': 'b', 'b': 'e', 'c': 'f'}
when it is supposed to be True
. I am sure that there is an issue in make_inv_dict
function; is it simply because adict
is not an appropriate variable name in adict = make_inv_dict(adict)
? Or is there another reason why the function returns a wrong outcome?
At least three problems with the function you've given:
adict == inv_dict
checks whether the dictionary is its own inverse, not merely that it's invertible.pop_item
to remove a key/value pair from the input dictionary, and then inserts it backwards, so the function operates in-place. By the time it's finished, adict
's original contents will be completely destroyed, so the comparison will be meaningless anyway.adict[key] = val
inserts the key/value pair in the original order; the inverse order should be adict[val] = key
. So this function doesn't do what its name promises, which is to make an inverse dictionary.It should be noted that if not for the destruction of the dictionary (2.), the mistakes (1.) and (3.) would cancel out, because the outcome of the function is to rebuild the original dictionary but without duplicate values.
I'm guessing some people will find this question if they're looking for a correct way to invert a dictionary, so here is one: this function returns the inverse dictionary if it's possible, or None
otherwise.
def invert_dict(d):
out = dict()
for k,v in dict.items():
if v in out:
return None
out[v] = k
return out
Helper function returning a boolean for whether a dictionary is invertible:
def is_invertible(d):
return invert_dict(d) is not None