尝试将列表添加到列表时获取TypeError

时间:2018-03-30 22:06:52

标签: python python-3.x python-2.7 list dictionary

这是我的代码:

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

我的主要人物:

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

我希望我的输入是:

  • 第一行 - {'cd': ['ab', 'bb'], 'dd': ['cc']}
  • 第二行 - {'d': ['a', 'b', 'c']}

但我得到了错误,如果我删除了我对列表进行排序的行,我的输入看起来像:

  • 第一行 - {'dd': ['cc'], 'cd': ['bb', ['ab']]}
  • 第二行 - {'d': ['a', ['c', ['b']]]}

我该怎么办?

4 个答案:

答案 0 :(得分:3)

您应该使用collections.defaultdict来解决此问题。

您的代码存在的问题是,要将列表元素添加到其他列表,您需要list.extend而不是list.append。这个答案提供了更多细节:

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']})

以上解决方案的说明

  • collections.defaultdict允许您为任意键指定默认值。
  • 在此实现中,默认值为空list
  • 因此,我们只需循环输入字典并使用list.append将原始字典中的键添加到设置为新字典键的值中。

答案 1 :(得分:1)

new_dict的值是列表。将列表附加到另一个列表时,您将获得嵌套列表。您希望通过另一个列表extend列表:

>>> 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']}

答案 2 :(得分:1)

您将列表附加到列表中,列表将其嵌入其中。你应该连接它们:

new_list += new_dict[new_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]

这也适用于defaultdict

答案 3 :(得分:0)

下面的函数给出了正确的结果:

 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