使用字典的get方法默认返回空列表却返回None
在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 个回答
问题在于,append
这个方法返回的是None
,而不是列表本身。所以
dict[i] = dict.get(i, []).append(j)
这行代码实际上把None
赋值给了dict[i]
不过,你可以用更简单的方法来做:
dict.setdefault( i, [] ).append( j )
.. 引用一下setdefault
的文档说明:
如果这个键已经在字典里,就返回它的值。如果没有,就插入这个键,并用默认值填充,然后返回这个默认值。
所以,如果键i
还不存在,它会创建这个键,并把默认值存进去;无论如何,它都会返回这个键对应的值——也就是一个指向列表的引用,这样你就可以直接修改这个列表。
要解决这个问题,你可以使用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。
不是说 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] =
,这正是导致错误信息的原因。