2013-11-26 34 views
0

我有以下项目(键 - 值对)的列表:在python中 - 如何将项目转换为字典?

items = [('A', 1), ('B', 1), ('B', 2), ('C', 3)] 

我想什么:

{ 
    'A' : 1, 
    'B' : [1,2] 
    'C' : 3 
} 

我天真的解决方案:

res = {} 
for (k,v) in items: 
    if k in res: 
     res[k].append(v) 
    else: 
     res[k] = [v] 

我期待对于一些优化更多pythonic解决方案,任何人?

+0

为什么downvoting? – mnowotka

+0

使用列表字典理解解决方案。 –

回答

4

使用可以在这里使用defaultdict。

from collections import defaultdict 

res = defaultdict(list) 
for (k,v) in items: 
    res[k].append(v) 
# Use as dict(res) 

编辑:

这是使用GROUPBY,但请注意,上述是更干净和整洁眼睛

>>> data = [('A', 1), ('B', 1), ('B', 2), ('C', 3)] 
>>> dict([(key,list(v[1] for v in group)) for (key,group) in groupby(data, lambda x: x[0])]) 
{'A': [1], 'C': [3], 'B': [1, 2]} 

下行:每一个元素是一个列表。根据需要将列表更改为生成器。


对所有单个项目列表转换为单个项目:

>>> res = # Array of tuples, not dict 
>>> res = [(key,(value[0] if len(value) == 1 else value)) for key,value in res] 
>>> res 
[('A', 1), ('B', [1, 2]), ('C', 3)] 
+0

任何避免显式循环的方法? – mnowotka

+0

不,你做的任何事情都必须通过“项目”循环。 –

0

这是很容易做到defaultdict,这可以从collections进口。

>>> from collections import defaultdict 
>>> items = [('A', 1), ('B', 1), ('B', 2), ('C', 3)] 
>>> d = defaultdict(list) 
>>> for k, v in items: 
    d[k].append(v) 
>>> d 
defaultdict(<class 'list'>, {'A': [1], 'C': [3], 'B': [1, 2]}) 

可以也使用字典理解:

>>> d = {l: [var for key, var in items if key == l] for l in {v[0] for v in items}} 
>>> d 
{'A': [1], 'C': [3], 'B': [1, 2]} 
+0

与其他答案相同的评论 - 是否有任何方法显式循环? – mnowotka

+0

@mnowotka该死的,对不起重复,但我的网络有点慢,所以我没有看到它。我很快就会给你另一个答案。 –

0

可以使用的WebOb multidict实现:

>>> from webob import multidict 
>>> a = multidict.MultiDict(items) 
>>> a.getall('B') 
[1,2] 
1

如果你不想使用defaultdict/groupby ,作品如下:

d = {} 
for k,v in items: 
    d.setdefault(k, []).append(v) 
+0

唯一的差点是所有的值都是列表。如果只有一个引用该键的值,OP不希望它们成为列表。 – FallenAngel

0

也许它看起来很丑,但它的工作原理。

In [1]: items = [('A', 1), ('B', 1), ('B', 2), ('C', 3)] 

In [2]: d = {} 

In [3]: map(lambda i: d.update({i[0]: i[1] if d.get(i[0], i[1]) == i[1] else [d[i[0]], i[1]]}), items) 
Out[3]: [None, None, None, None] 

In [4]: print d 
{'A': 1, 'C': 3, 'B': [1, 2]} 

else分支,我们可以检查是否d[i[0]]返回一个列表。