为字典中的一个键附加多个值[重复]
- 2025-01-15 08:45:00
- admin 原创
- 91
问题描述:
我是 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
解决方案 1:
如果我可以重新表述您的问题,您想要的是一个以年份为键的字典,以及一个包含与该年份相关的值列表的数组,对吗?以下是我的做法:
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]
}
一般来说,创建“并行数组”是一种糟糕的编程习惯,其中的项目通过具有相同的索引而隐式地相互关联,而不是成为包含它们的容器的适当子项。
解决方案 2:
最好使用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]})
这样,您就不必担心是否看到与年份相关的数字。您只需添加并忘记,因为您知道缺少的键将始终是一个列表。如果某个键已经存在,则只需将其附加到该键即可。
解决方案 3:
您可以使用setdefault
。
for line in list:
d.setdefault(year, []).append(value)
这是可行的,因为 setdefault 不仅会返回列表,还会将其设置在字典上,而且列表是可变的,因此将其附加到 setdefault 返回的版本与将其附加到字典本身的版本相同。如果这有任何意义的话。
解决方案 4:
d = {}
# import list of year,value pairs
for year,value in mylist:
try:
d[year].append(value)
except KeyError:
d[year] = [value]
Python 方式——获得原谅比请求许可更容易!
解决方案 5:
以下是使用运算符执行此操作的另一种方法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)
解决方案 6:
如果将这些值放入元组列表中,则更容易。为此,您可以使用列表切片和 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
接受一个键和一个默认值,并返回关联值,或者如果没有当前值,则返回默认值。在这种情况下,我们将获得一个空列表或已填充列表,然后将当前值附加到该列表。
解决方案 7:
如果你想要一个(几乎)一行代码:
从集合导入双端队列
d = {}
deque((d.setdefault(year, []).append(value) 表示年份,source_of_data 中的值),maxlen=0)
使用dict.setdefault
,您可以将“检查键是否已存在,如果不存在则创建新列表”的想法封装到单个调用中。这允许您编写一个生成器表达式,该表达式被deque
尽可能高效地使用,因为队列长度设置为零。双端队列将立即被丢弃,结果将为d
。
我只是为了好玩才这么做的。我不建议使用它。通过双端队列使用任意可迭代对象是有时间和地点的,而这绝对不是。