user9576804
user9576804

Reputation: 3

Getting TypeError when trying to add lists to list

This is my code:

def inverse_dict(my_dict):
    new_dict = {}
    new_key = ''
    for new_value in my_dict:
        new_list = [new_value]
        new_key = my_dict[new_value]
        if new_key in new_dict:
            new_list.append(new_dict[new_key])
            new_list = sorted(new_list)
        new_dict[new_key] = new_list
    return new_dict

And my main:

def main():
    print(inverse_dict({'cc': 'dd', 'ab': 'cd', 'bb': 'cd'}))
    print(inverse_dict({'b': 'd', 'c': 'd', 'a': 'd'}))

I want that my input will be:

But instead I get error and if I delete the line that i sort my list my input looks like:

what can I do?

Upvotes: 1

Views: 187

Answers (4)

ErdoganOnal
ErdoganOnal

Reputation: 880

Below function gives correct result:

 def inverse_dict(dict_):
        inverse_dict = dict() # Set an empty dictionary
        for key, value in dict_.items():
            try:
                # If list, add key into list; otherwise it will throw exeption
                inverse_dict[value].append(key)
            except AttributeError:
                # AttributeError means value has item but not list
                inverse_dict[value] = [inverse_dict[value], key]
            except KeyError:
                # KeyError means there isn't any item in the new dictionary
                inverse_dict[value] = key
        return inverse_dict

Upvotes: 0

Barmar
Barmar

Reputation: 781004

You're appending a list to a list, which nests it inside. You should concatenate them:

new_list += new_dict[new_key]

But even simpler would be to not create a new list, just append to the list that's in the key.

for new_key, new_value in enumerate(my_dict):
    if new_value in new_dict:
        new_dict[new_value].append(new_key)
        new_dict[new_value] = sorted(new_dict[new_value])
    else
        new_dict[new_value] = [new_key]

This is also a good use for a defaultdict.

Upvotes: 1

jpp
jpp

Reputation: 164673

You should use collections.defaultdict for this problem.

The problem with your code is that, to add the elements of a list to another list, you need list.extend instead of list.append. This answer provides more detail:

Difference between append vs. extend list methods in Python

from collections import defaultdict

def inverse_dict(d):
    res = defaultdict(list)
    for k, v in d.items():
        res[v].append(k)

    return res

print(inverse_dict({'cc': 'dd', 'ab': 'cd', 'bb': 'cd'}))
# defaultdict(<class 'list'>, {'dd': ['cc'], 'cd': ['ab', 'bb']})

print(inverse_dict({'b': 'd', 'c': 'd', 'a': 'd'}))
# defaultdict(<class 'list'>, {'d': ['b', 'c', 'a']})

Explanation for above solution

  • collections.defaultdict allows you to specify a default value for arbitrary keys.
  • In this implementation, the default value is an empty list.
  • Therefore, we simply loop through the input dictionary and use list.append to add keys from the original dictionary to values set as keys of your new dictionary.

Upvotes: 3

erip
erip

Reputation: 16935

The values of new_dict are lists. When you append a list to another list, you get nested lists. You want to extend the list by another list:

>>> def inverse_dict(my_dict):
...     new_dict = {}
...     new_key = ''
...     for new_value in my_dict:
...         new_list = [new_value]
...         new_key = my_dict[new_value]
...         if new_key in new_dict:
...             new_list.extend(new_dict[new_key])
...             new_list = sorted(new_list)
...         new_dict[new_key] = new_list
...     return new_dict
...
>>> print(inverse_dict({'cc': 'dd', 'ab': 'cd', 'bb': 'cd'}))
{'dd': ['cc'], 'cd': ['ab', 'bb']}
>>> print(inverse_dict({'b': 'd', 'c': 'd', 'a': 'd'}))
{'d': ['a', 'b', 'c']}

Upvotes: 1

Related Questions