【问题标题】:Python: Error retrieving and modifying values in a dictionary using .append()?Python:使用 .append() 检索和修改字典中的值时出错?
【发布时间】:2013-04-04 15:03:51
【问题描述】:

假设我有一个字符列表,我想将每个字符映射到它在列表中出现的次数。下面的代码实现了这一点:

characters = ['a','b','c','a']
d = {}
for ch in characters:
   d[ch] = d.get(ch,0) + 1
return d

现在让我们说,我不想将每个字符映射到它在列表中出现的次数,而是将它映射到一个 1 的列表,其中每个 1 代表列表中的一次出现。例如,像 {a:[1,1], b:[1], c:[1]}。我使用相同的格式,但它不起作用。谁能解释为什么不呢?

characters = ['a','b','c','a']
d = {}
for ch in characters:
   d[ch] = d.get(ch,[]).append(1)
#print type(d['a'])
return d

我得到 AttributeError: 'NoneType' 对象没有属性 'append',即使如果我删除 for 循环中的 .append() 打印类型 (d['a']) 会返回“list”。谢谢!

【问题讨论】:

    标签: python dictionary key append


    【解决方案1】:

    您将d[ch] 的值分配给[].append 的返回值。这样想你的代码相当于

    tmp = d.get(ch,[])
    d[ch] = tmp.append(1)
    

    试试这个:

    d[ch] = d.get(ch,[])
    d[ch].append(1)
    

    【讨论】:

    • 感谢您的回复。你能进一步解释这两个代码之间的区别吗?例如,对于第一次迭代,我不会获得 d['a'] = [].append(1) 吗?这意味着 d['a'] 现在是 [1]。通过最后一次迭代,d['a'] = d.get('a',[]).append(1)。由于 d['a'] 已经定义,我不会得到 d['a'] = [1].append(1),在这种情况下我会得到 [1,1]?谢谢。
    • @user2241856 在交互式解释器中尝试m = [1]; m.append(1)。它返回[1, 1],但None - 追加是通过修改m来完成的。
    【解决方案2】:

    使用pythondir函数

    list 有附加方法

    dist 没有附加方法

    >>> characters = []
    >>> d = {}
    >>> dir(characters)
    ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
    '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', 
    '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', 
    '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', 
    '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', 
    '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', 
    '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append',
    'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    
    >>> dir(d)
    ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', 
    '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', 
    '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', 
    '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', 
    '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 
    'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 
    'popitem', 'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues']
    

    【讨论】:

    • 这是不同版本的python吗?我有目录(字符),包括追加。
    • 你的角色必须是set@Timothy,你应该解决这个问题
    • 设置字符和d变量
    【解决方案3】:
    characters = ['a','b','c','a']
    d = {}
    for ch in characters:
       d[ch] = d.get(ch,[]).append(1)
    #print type(d['a'])
    return d
    

    dict.get 返回键 ch 处的值,如果它不存在,则返回您提供的默认值,即您创建的列表 []。无论如何,我认为您可能会感到困惑,因为d.get 没有设置任何值,它只返回一个。然后您将1 附加到此列表中。 .append 是一个就地操作,因此它不会像您预期的那样返回后附加列表,它只是返回 None 以表示它不应该按照您的方式使用。你可以做的是

    d.setdefault(ch, []).append(1)
    

    这符合您的期望;) 为了避免这种疯狂的语法,您可以像这样使用collections.defaultdict

    d = defaultdict(list)
    d[ch].append(1)
    

    看起来干净多了

    【讨论】:

      【解决方案4】:

      d[ch] = d.get(ch,[]).append(1) 行将d[ch] 设置为append 函数返回的值,即None。改为这样做:

      d[ch] = d.get(ch, [])
      d[ch].append(1)
      

      【讨论】:

      • 啊,这很有道理。谢谢!
      • @user2241856 如果你觉得有用,请在答案打勾。
      【解决方案5】:

      这是我提出的解决方案:

      characters = ['a','b','c','a']
      d = {}
      for ch in characters:
          d.setdefaultappend(ch, []).append(1)
      return d
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 2018-02-12
        • 1970-01-01
        • 2018-07-10
        • 2021-09-23
        • 2022-01-14
        相关资源
        最近更新 更多