列表转换为每个键有多个值的字典转换?

时间:2011-03-21 13:28:47

标签: python list dictionary type-conversion

我有一个包含键/值对的Python列表:

l=[ [1, 'A'], [1, 'B'], [2, 'C'] ]

我想将列表转换为字典,其中每个键的多个值将聚合为元组:

{ 1:('A', 'B'), 2:('C',) }

迭代解决方案很简单:

l=[ [1, 'A'], [1, 'B'], [2, 'C'] ]
d={}
for pair in l:
    if d.has_key(pair[0]):
        d[pair[0]]=d[pair[0]]+tuple(pair[1])
    else:
        d[pair[0]]=tuple(pair[1])

print d

{1: ('A', 'B'), 2: ('C',)}

这项任务是否有更优雅的Pythonic解决方案?

6 个答案:

答案 0 :(得分:49)

from collections import defaultdict

d1 = defaultdict(list)

for k, v in l:
    d1[k].append(v)

d = dict((k, tuple(v)) for k, v in d1.iteritems())

d现在包含{1: ('A', 'B'), 2: ('C',)}

d1是一个临时的defaultdict,列表为值,将在最后一行转换为元组。这样,您将附加到列表而不是在主循环中重新创建元组。

答案 1 :(得分:10)

这种方法相对有效且非常紧凑:

reduce(lambda x, (k,v): x[k].append(v) or x, l, defaultdict(list))

在Python3中,这变得显而易见(导出显式):

dict(functools.reduce(lambda x, d: x[d[0]].append(d[1]) or x, l, collections.defaultdict(list)))

请注意,reduce已移至functools并且lambdas不再接受元组。此版本仍适用于2.6和2.7。

答案 2 :(得分:9)

使用列表而不是元组作为dict值:

l=[ [1, 'A'], [1, 'B'], [2, 'C'] ]
d={}
for key, val in l:
    d.setdefault(key, []).append(val)

print d

答案 3 :(得分:3)

键是否已在输入列表中排序?如果是这种情况,您就有了一个功能性解决方案:

import itertools

lst = [(1, 'A'), (1, 'B'), (2, 'C')]
dct = dict((key, tuple(v for (k, v) in pairs)) 
           for (key, pairs) in itertools.groupby(lst, lambda pair: pair[0]))
print dct
# {1: ('A', 'B'), 2: ('C',)}

答案 4 :(得分:1)

我有一个创建的值列表,如下所示:

performance_data = driver.execute_script('return window.performance.getEntries()')  

然后我必须将数据(名称和持续时间)存储在具有多个值的字典中:

dictionary = {}
    for performance_data in range(3):
        driver.get(self.base_url)
        performance_data = driver.execute_script('return window.performance.getEntries()')
        for result in performance_data:
            key=result['name']
            val=result['duration']
            dictionary.setdefault(key, []).append(val)
        print(dictionary)

答案 5 :(得分:0)

我的数据在Pandas.DataFrame中

myDict = dict()

for idin set(data['id'].values):
    temp = data[data['id'] == id]
    myDict[id] = temp['IP_addr'].to_list()
    
myDict

给我一​​个键,ID,到> = 1 IP_addr 的映射。保证第一个IP_addr。即使temp['IP_addr'].to_list() == []

,我的代码也可以正常工作
{'fooboo_NaN': ['1.1.1.1', '8.8.8.8']}