【问题标题】:append multiple values for one key in a dictionary [duplicate]为字典中的一个键附加多个值[重复]
【发布时间】:2011-03-13 01:36:20
【问题描述】:

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


【解决方案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]
}

一般来说,创建“并行数组”是一种糟糕的编程习惯,其中项通过具有相同的索引而不是包含它们的容器的适当子项而隐式地相互关联。

【讨论】:

  • 这绝对是正确的方法,尽管考虑到dict.setdefault()collections.defaultdict 等很酷的技巧作为现代Python 安装可用的默认工具集的一部分,它不一定是最简洁的。
  • 如果你使用 defaultdict 将其设置为一个列表:dd = defaultdict(list)
  • 与其他答案中描述的其他方法相比,这种方法的性能非常差。
【解决方案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]})

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

【讨论】:

  • 这是最好的答案。这里的目的是创建一个列表字典,最简单的方法是使用defaultdict(list)。恭喜
  • 非常整洁干净的方法。
【解决方案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 方式 - 获得宽恕比请求许可更容易!

    【讨论】:

    • 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) for year, source_of_data 中的值), maxlen=0)

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

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

        【讨论】:

        • 如果我使用data = [(2010, 2), (2009, 4), (1989, 8), (2009, 7)],它会返回deque([])
        • @Cleb。结果在d 中。双端队列应该被丢弃。它的唯一功能是尽快处理生成器。
        • 哎呀,愚蠢的我;那么它实际上工作得很好......
        • @Cleb。我添加了一个澄清的句子。创建一个对象只是为了扔掉它并不是那么直观。我想知道您是否可以直接使用__init__ 方法。类似deque.__init__(None, iterable, maxlen=0)
        • @Cleb。原来你不能放弃双端队列对象:TypeError: descriptor '__init__' requires a 'collections.deque' object but received a 'NoneType'
        猜你喜欢
        • 2017-09-07
        • 1970-01-01
        • 2019-06-09
        • 2014-04-22
        • 2016-10-21
        • 2016-05-07
        • 2014-04-05
        • 1970-01-01
        • 2019-04-27
        相关资源
        最近更新 更多