使用字典的get方法默认返回空列表却返回None

33 投票
5 回答
29836 浏览
提问于 2025-04-16 16:20

在Python中,我想用字典的获取方法来创建一个数组字典,默认情况下提供一个空列表,然后再填充信息,比如:

dct = {}
for i in range(0, 10):
    for j in range(0, 100):
        dct[i] = dct.get(i, []).append(j)

但是当我尝试上面的代码时,没有出现任何异常,但我的列表却变成了这样:

AttributeError: 'NoneType' object has no attribute 'append'

列表有一个append方法,所以我把测试简化成了下面这样:

dct = {}
for i in range(0, 10):
    dct[i] = dct.get(i, []).append(i)

结果是这样的:

{0: None, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None, 7: None, 8: None, 9: None}

所以我的问题是,为什么dct.get(i, [])默认返回的是None而不是[]?用dct.get(i, list())也有同样的问题,我有点困惑。

5 个回答

6

问题在于,append这个方法返回的是None,而不是列表本身。所以

dict[i] = dict.get(i, []).append(j)这行代码实际上把None赋值给了dict[i]

不过,你可以用更简单的方法来做:

dict.setdefault( i, [] ).append( j )

.. 引用一下setdefault的文档说明:

如果这个键已经在字典里,就返回它的值。如果没有,就插入这个键,并用默认值填充,然后返回这个默认值。

所以,如果键i还不存在,它会创建这个键,并把默认值存进去;无论如何,它都会返回这个键对应的值——也就是一个指向列表的引用,这样你就可以直接修改这个列表。

39

要解决这个问题,你可以使用Python里的defaultdict。当你第一次使用一个不存在的键时,defaultdict的构造函数里的参数会被用来创建一个值(在这个例子中,是一个列表)。

http://docs.python.org/library/collections.html#defaultdict-examples

from collections import defaultdict 

d = defaultdict(list)
for i in range( 0, 10 ):
    for j in range( 0, 100 ):
        d[i].append( j )

如果你想做一些更复杂的事情,也可以把一个函数作为参数传给defaultdict。

31

不是说 dict.get( i, [] ) 返回了 None,而是 append 这个方法出了问题。你可能想用 dict.setdefault(i, []).append(j),或者干脆一开始就用 defaultdict

下面是你可以这样做的示例:

d = {}
for i in range( 0, 10 ):
    for j in range( 0, 100 ):
        d.setdefault( i, [] ).append( j )

注意我把 dict 改成了 d,因为在 Python 中 dict 已经有特定的意思(你在重新定义它),而且我去掉了多余的 dict[i] =,这正是导致错误信息的原因。

撰写回答