在字典中为一个键追加多个值

172 投票
7 回答
822492 浏览
提问于 2025-04-16 00:58

我刚开始学习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 个回答

57

你可以使用 setdefault 方法。

for line in list:  
    d.setdefault(year, []).append(value)

这个方法之所以有效,是因为 setdefault 不仅会在字典中设置一个值,还会返回这个值。而且因为列表是可变的,所以对 setdefault 返回的列表进行添加操作,实际上就是在字典里面的那个列表上添加内容。这么说你能理解吗?

123

你最好使用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]})

这样你就不用担心某个年份是否已经有数字了。你只需要添加就行,完全不用操心,因为缺失的键总是会是一个列表。如果这个键已经存在了,那就直接在它后面添加内容。

240

如果我能换个说法,你想要的是一个字典,里面的键是年份,每个年份对应一个数组,这个数组里包含与该年份相关的一些值,对吧?我会这样做:

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

一般来说,创建“平行数组”是一种不太好的编程习惯。平行数组是指通过相同的索引来隐式关联的项目,而不是把它们放在一个包含它们的容器里,这样更合理。

撰写回答