我怎样才能将python元组转换为dict

时间:2014-09-26 08:33:10

标签: python dictionary

如何转换以下元组列表:

t = [("x", "1","11"),("x", "2","22"),("x", "3","33"),
     ("y", "3","00"),("z", "2","222"), ("z", "3","333")]

到这个带字典的列表列表中?

[["x",{"1":"11","2":"22","3":"33"}],
 ["y",{"3":"00"}],
 ["z",{"2":"222","3":"333"}]]

2 个答案:

答案 0 :(得分:2)

我是列表理解的忠实粉丝。这是一个使用它的简单解决方案:

keys = set(map(lambda x: x[0], t))
d = [[k, dict([(y, z) for x, y, z in t if x is k])] for k in keys]

结果:

[['y', {'3': '00'}],
 ['x', {'1': '11', '2': '22', '3': '33'}],
 ['z', {'2': '222', '3': '333'}]]

对于较大的列表,这将是缓慢的,因为d是在O(N ^ 2)时间内计算的。

答案 1 :(得分:1)

分两步:创建字典并跟踪您看过第一个元素的顺序,然后从中构建一个列表:

order = []
mapping = {}
for outer, inner, value in t:
    if outer not in order:
        order.append(outer)
    mapping.setdefault(outer, {})[inner] = value

result = [(k, mapping[k]) for k in order]

或使用collections.OrderedDict() object跟踪您第一次看到外键的顺序:

from collections import OrderedDict

mapping = OrderedDict()
for outer, inner, value in t:
    mapping.setdefault(outer, {})[inner] = value

result = mapping.items()

如果订单不重要,请使用第一个版本并移除对order的所有引用(3行),最后只使用mapping.items()

如果您的输入始终按每个元组的第一个元素排序,则可以使用itertools.groupby()

from itertools import groupby
from operator import itemgetter

result = [(k, {k: v for _, k, v in g}) for k, g in groupby(t, itemgetter(0))]

演示:

>>> t = [("x", "1","11"),("x", "2","22"),("x", "3","33"),
...      ("y", "3","00"),("z", "2","222"), ("z", "3","333")]
>>> order = []
>>> mapping = {}
>>> for outer, inner, value in t:
...     if outer not in order:
...         order.append(outer)
...     mapping.setdefault(outer, {})[inner] = value
... 
>>> [(k, mapping[k]) for k in order]
[('x', {'1': '11', '3': '33', '2': '22'}), ('y', {'3': '00'}), ('z', {'3': '333', '2': '222'})]
>>> mapping.items()  # ignoring order
[('y', {'3': '00'}), ('x', {'1': '11', '3': '33', '2': '22'}), ('z', {'3': '333', '2': '222'})]
>>> from collections import OrderedDict
>>> mapping = OrderedDict()
>>> for outer, inner, value in t:
...     mapping.setdefault(outer, {})[inner] = value
... 
>>> mapping.items()
[('x', {'1': '11', '3': '33', '2': '22'}), ('y', {'3': '00'}), ('z', {'3': '333', '2': '222'})]
>>> from itertools import groupby
>>> from operator import itemgetter
>>> [(k, {k: v for _, k, v in g}) for k, g in groupby(t, itemgetter(0))]
[('x', {'1': '11', '3': '33', '2': '22'}), ('y', {'3': '00'}), ('z', {'3': '333', '2': '222'})]