By Python 101


2019-11-08 14:09:29 8 Comments

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?

2 comments

@kaya3 2019-11-08 14:13:42

At least three problems with the function you've given:

  1. The condition adict == inv_dict checks whether the dictionary is its own inverse, not merely that it's invertible.
  2. It uses 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.
  3. The line 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

@Kapil 2019-11-08 14:32:51

My Answer:

def is_invertible(dict_var):
    return len(dict_var.values()) == len(list(set(dict_var.values())))

@kaya3 2019-11-09 21:25:29

No need to convert the set into a list before you do len - it works perfectly well (and faster) to write len(set(...)).

Related Questions

Sponsored Content

11 Answered Questions

[SOLVED] How to remove a key from a Python dictionary?

41 Answered Questions

[SOLVED] How do I merge two dictionaries in a single expression?

28 Answered Questions

[SOLVED] How do I check if a list is empty?

  • 2008-09-10 06:20:11
  • Ray Vega
  • 2505268 View
  • 3235 Score
  • 28 Answer
  • Tags:   python list

27 Answered Questions

[SOLVED] What is the best way to iterate over a dictionary?

  • 2008-09-26 18:20:06
  • Jake Stewart
  • 1468331 View
  • 2426 Score
  • 27 Answer
  • Tags:   c# dictionary loops

17 Answered Questions

14 Answered Questions

[SOLVED] Add new keys to a dictionary?

37 Answered Questions

[SOLVED] How do I check whether a file exists without exceptions?

16 Answered Questions

[SOLVED] Check if a given key already exists in a dictionary

  • 2009-10-21 19:05:09
  • Mohan Gulati
  • 3184651 View
  • 2683 Score
  • 16 Answer
  • Tags:   python dictionary

10 Answered Questions

[SOLVED] Iterating over dictionaries using 'for' loops

34 Answered Questions

[SOLVED] How do I sort a dictionary by value?

Sponsored Content