Python 为字典中的一个键追加多个值

Python 为字典中的一个键追加多个值,python,dictionary,key-value,Python,Dictionary,Key Value,我是python新手,我有一份每年的年份和值列表。我想做的是检查字典中是否已经存在年份,如果存在,则将该值附加到特定键的值列表中 例如,我有一个年份列表,每年有一个值: 2010 2 2009 4 1989 8 2009 7 我想做的是用年份作为键,用那个些数字作为值来填充字典。但是,如果我列出了两次2009,我希望将第二个值附加到该字典中的值列表中,因此我希望: 2010: 2 2009: 4, 7 1989: 8 现在我有以下几点: d = d

我是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  

最好使用(在Python2.5中添加的)。这允许您指定缺失键的默认对象类型(例如
列表

因此,与其先创建一个不存在的键,然后附加到该键的值,不如去掉中间人,直接附加到不存在的键,以获得所需的结果

使用您的数据的快速示例:

>>> 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]})
>>从集合导入defaultdict
>>>数据=[(2010,2)、(2009,4)、(1989,8)、(2009,7)]
>>>d=默认DICT(列表)
>>>d
defaultdict(,{})
>>>数据中的年、月:
...     d【年】。追加(月)
... 
>>>d
defaultdict({2009:[4,7],2010:[2],1989:[8]})

这样,你就不必担心你是否看到了与一年相关的数字。您只需添加并忘记,因为您知道缺少的键将始终是一个列表。如果一个键已经存在,那么它将被追加到。

您可以使用
setdefault

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

这是因为setdefault返回列表以及在字典上设置列表,并且列表是可变的,因此将其附加到setdefault返回的版本与将其附加到字典本身内部的版本相同。如果这有意义的话。

如果我可以重新表述你的问题,你想要的是一本以年份为键的字典,以及一个每年的数组,其中包含与该年份相关的值列表,对吗?我是这样做的:

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]]
你应该在几年后得到一本字典,它看起来如下:

{
    "2010": [2],
    "2009": [4,7],
    "1989": [8]
}
一般来说,创建“并行数组”是一种糟糕的编程实践,在这种情况下,项通过具有相同的索引而不是包含它们的容器的适当子项来隐式地相互关联

d = {} 

# import list of year,value pairs

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

Python的方式-接受原谅比请求允许更容易

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

data_in = [2010,2,2009,4,1989,8,2009,7]
data_pairs = zip(data_in[::2],data_in[1::2])
Zip获取任意数量的列表,在本例中是中
数据的偶数和奇数项,并将它们组合成一个元组

现在我们可以使用
setdefault
方法

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

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

下面是使用
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)
如果您想要(几乎)一个班轮:

from collections import deque d = {} deque((d.setdefault(year, []).append(value) for year, value in source_of_data), maxlen=0) 从集合导入deque d={} deque((d.setdefault(year,[])。为year追加(value),在数据源中添加值,maxlen=0) 使用
dict.setdefault
,您可以将“检查密钥是否已存在,如果不存在则创建新列表”的思想封装到一个调用中。这允许您尽可能高效地编写一个生成器表达式,该表达式由
deque
使用,因为队列长度设置为零。deque将立即被丢弃,结果将显示在
d


我只是为了好玩才这么做的。我不推荐使用它。有一个时间和一个地方可以通过deque消费任意的iterables,而这绝对不是它

这绝对是正确的方法,尽管考虑到诸如
dict.setdefault()
collections.defaultdict
等酷炫技巧的可用性,这不一定是最简洁的方法,因为它们是现代Python安装可用的默认工具集的一部分。如果确实使用defaultdict,请将其设置为列表:dd=defaultdict(list)与其他答案中描述的其他方法相比,这种方法的性能非常差。python的方法是不复制功能。我看不出这里有什么重复。另一个类似的问题:如果我使用
data=[(2010,2)、(2009,4)、(1989,8)、(2009,7)]
,它将返回
deque([])
@Cleb。结果显示为
d
。应该扔掉这顶帽子。它唯一的功能就是尽快处理发电机;那么它实际上运行得很好…@Cleb。我加了一句澄清的话。创建一个对象只是为了扔掉它并不是那么直观。我想知道您是否可以直接使用
\uuuu init\uuu
方法。类似于
deque.\uuuu init\uuuuu(无,iterable,maxlen=0)
@Cleb。事实证明,您不能放弃deque对象:
TypeError:descriptor'\uuu init\uuuu'需要一个“collections.deque”对象,但收到了一个“NoneType”
这是最好的答案。这里的目的是创建列表的dict,最简单的方法是使用
defaultdict(list)
。恭喜你,这是一个非常整洁的方法。