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

我是 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
759062 次浏览

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

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

你可以使用 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]]

在 years _ dict 中,你应该得到的是一本类似于下面这样的字典:

{
"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 接受任意数量的列表,在本例中是 data_in的偶数和奇数条目,并将它们放在一个 tuple 中。

现在我们可以使用 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)

使用 dict.setdefault,您可以将“检查密钥是否已经存在,如果不存在,则创建一个新列表”的想法封装到一个调用中。这允许您编写一个生成器表达式,由于队列长度设置为零,因此 deque尽可能有效地使用这个表达式。Deque 将被立即丢弃,结果将在 d中。

我这么做只是为了好玩。我不建议使用它。有一个时间和地点可以通过 deque 使用任意的迭代,而这个时间和地点肯定不行。