【问题标题】:Getting TypeError when trying to add lists to list尝试将列表添加到列表时出现 TypeError
【发布时间】:2018-03-30 22:06:52
【问题描述】:

这是我的代码:

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

我能做什么?

【问题讨论】:

  • 当您尝试对new_list 进行排序时,您可能混合了字符串和列表。
  • 使用extend 而不是append
  • Python 3 不会试图猜测您想如何比较完全不同类型的对象。您是否希望所有列表都出现在所有字符串之前?毕竟所有的字符串?或者将字符串视为单元素字符串列表?无论您想要什么,您都可以为其编写一个关键函数并将其传递给sorted,但您必须先决定您想要什么。
  • 误导性标题...

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


【解决方案1】:

你应该使用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 将原始字典中的键添加到设置为新字典键的值中。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      您将一个列表附加到一个列表中,该列表将其嵌套在其中。您应该将它们连接起来:

      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 也很有用。

      【讨论】:

        【解决方案4】:

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

         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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-01-21
          • 2021-07-29
          • 2020-09-26
          • 2012-02-20
          • 1970-01-01
          • 2023-03-05
          • 1970-01-01
          • 2023-01-13
          相关资源
          最近更新 更多