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

时间:2010-07-07 21:50:48

标签: python dictionary key-value

我是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 个答案:

答案 0 :(得分:172)

如果我可以改写你的问题,你想要的是一个字典,其中包含年份作为键和每年包含与该年相关的值列表的数组,对吧?我就是这样做的:

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

一般来说,创建“并行数组”的编程实践很差,其中项目通过具有相同的索引而不是包含它们的容器的正确子项而隐式地相互关联。

答案 1 :(得分:89)

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

这样您就不必担心自己是否看过与一年相关的数字。您只需追加并忘记,知道丢失的密钥将始终是一个列表。如果一个密钥已经存在,那么它将被附加到。

答案 2 :(得分:38)

您可以使用setdefault

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

这是有效的,因为setdefault返回列表并将其设置在字典上,并且因为列表是可变的,所以附加到setdefault返回的版本与将其附加到字典本身内的版本相同。如果这是有道理的。

答案 3 :(得分:17)

d = {} 

# import list of year,value pairs

for year,value in mylist:
    try:
        d[year].append(value)
    except KeyError:
        d[year] = [value]

Python方式 - 获得宽恕比获得许可更容易!

答案 4 :(得分:10)

以下是使用not in运算符执行此操作的另一种方法:

# define an empty dict
years_dict = dict()

for line in list:
    # here define what key is, for example,
    key = line[0]
    # check if key is already present in dict
    if key not in years_dict:
        years_dict[key] = []
    # append some value 
    years_dict[key].append(some.value)

答案 5 :(得分:4)

如果将这些值放入元组列表中会更容易。为此,您可以使用列表切片和zip函数。

data_in = [2010,2,2009,4,1989,8,2009,7]
data_pairs = zip(data_in[::2],data_in[1::2])

Zip采用任意数量的列表,在本例中为data_in的偶数和奇数项,并将它们组合成一个元组。

现在我们可以使用setdefault方法。

data_dict = {}
for x in data_pairs:
    data_dict.setdefault(x[0],[]).append(x[1])

setdefault获取键和默认值,并返回关联值,或者如果没有当前值,则返回默认值。在这种情况下,我们将获得一个空的或填充的列表,然后我们将当前值附加到。

答案 6 :(得分:2)

如果你想要一个(几乎)单行:

from collections import deque

d = {}
deque((d.setdefault(year, []).append(value) for year, value in source_of_data), maxlen=0)

使用deque,您可以将“检查密钥是否已经存在并且如果没有新的列表”的想法封装到单个调用中。这允许您编写由d尽可能有效地使用的生成器表达式,因为队列长度设置为零。 deque将立即被丢弃,结果将在{{1}}。

这是我为了好玩而做的事情。我不建议使用它。有一个时间和地点通过双端队列消耗任意迭代,这绝对不是它。