附加在字典[重复用于一个键的多个值

问题描述 投票:117回答:7

这个问题已经在这里有一个答案:

我是新来的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  
python dictionary key-value
7个回答
184
投票

如果我能改写你的问题,你想要的是与年键的字典,每年含当年关联的值的列表数组,对不对?以下是我想做到这一点:

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

在一般情况下,它的编程习惯差打造“平行阵列”,其中数据项相互具有相同指数而不是涵盖他们两个容器的适当孩子隐含有关。


98
投票

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

这样,您就不必担心你是否已经看到了一年或不相关的数字。你只是追加忘记,知道丢失的钥匙将永远是一个列表。如果键已经存在,那么它只会被追加到。


40
投票

您可以使用setdefault

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

这工作,因为setdefault返回列表以及设置它的字典,因为列表是可变的,附加到由setdefault返回的版本是一样的,因为它附加到字典里面自己的版本。如果那有意义的话。


17
投票
d = {} 

# import list of year,value pairs

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

Python是这样 - 这是更容易得到原谅比要求许可!


12
投票

下面是这样使用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)

4
投票

如果你把这些值转换成元组的列表更容易。要做到这一点,你可以使用列表分片和压缩功能。

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

邮编需要列出任意数量的,在这种情况下data_in的偶数和奇数项,并把它们连成一个元组。

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

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

setdefault需要一个键和一个默认值,并返回要么关联的值,或者如果没有当前值,默认值。在这种情况下,我们要么得到一个空或填充的列表,我们再追加当前值。


2
投票

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

from collections import deque

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

使用dict.setdefault,你可以封装的想法“检查键已经存在,如果不做出新的列表”成一个单一的电话。这允许你写自队列长度被设置为零,这是由deque尽可能有效地消耗了发电机的表达。双端队列会被立即丢弃,结果将在d

这是我刚做的乐趣。我不建议使用它。有一段时间,并通过双端队列消费任意iterables的地方,这绝对不是。

© www.soinside.com 2019 - 2024. All rights reserved.