在字典中为一个键追加多个值
我刚开始学习Python,手里有一组年份和每年对应的值。我想做的是检查这些年份是否已经在一个字典里,如果存在,就把对应的值添加到那个年份的值列表中。
比如说,我有一组年份,每年都有一个值:
2010
2
2009
4
1989
8
2009
7
我想用这些年份作为字典的键,把这些单个数字作为值填进去。但是,如果2009这个年份出现了两次,我想把第二个值添加到字典中那个年份的值列表里,所以我希望得到:
2010: 2
2009: 4, 7
1989: 8
现在我有以下内容:
d = dict()
years = []
(get 2 column list of years and values)
for line in list:
year = line[0]
value = line[1]
for line in list:
if year in d.keys():
d[value].append(value)
else:
d[value] = value
d[year] = year
7 个回答
你可以使用 setdefault
方法。
for line in list:
d.setdefault(year, []).append(value)
这个方法之所以有效,是因为 setdefault
不仅会在字典中设置一个值,还会返回这个值。而且因为列表是可变的,所以对 setdefault
返回的列表进行添加操作,实际上就是在字典里面的那个列表上添加内容。这么说你能理解吗?
你最好使用collections.defaultdict
(这个功能在Python 2.5中加入的)。它可以让你指定一个默认的对象类型,当你查找一个不存在的键时,比如说可以是一个list
(列表)。
这样一来,你就不需要先检查这个键是否存在,如果不存在再创建它,然后再把值添加进去。你可以直接对不存在的键进行添加,这样就省去了中间的步骤,直接得到你想要的结果。
这里有个用你数据的简单例子:
>>> from collections import defaultdict
>>> data = [(2010, 2), (2009, 4), (1989, 8), (2009, 7)]
>>> d = defaultdict(list)
>>> d
defaultdict(<type 'list'>, {})
>>> for year, month in data:
... d[year].append(month)
...
>>> d
defaultdict(<type 'list'>, {2009: [4, 7], 2010: [2], 1989: [8]})
这样你就不用担心某个年份是否已经有数字了。你只需要添加就行,完全不用操心,因为缺失的键总是会是一个列表。如果这个键已经存在了,那就直接在它后面添加内容。
如果我能换个说法,你想要的是一个字典,里面的键是年份,每个年份对应一个数组,这个数组里包含与该年份相关的一些值,对吧?我会这样做:
years_dict = dict()
for line in list:
if line[0] in years_dict:
# append the new number to the existing array at this slot
years_dict[line[0]].append(line[1])
else:
# create a new array in this slot
years_dict[line[0]] = [line[1]]
最后你得到的years_dict应该是一个看起来像下面这样的字典:
{
"2010": [2],
"2009": [4,7],
"1989": [8]
}
一般来说,创建“平行数组”是一种不太好的编程习惯。平行数组是指通过相同的索引来隐式关联的项目,而不是把它们放在一个包含它们的容器里,这样更合理。