2014-09-26 25 views
-5

我如何的元组下面的列表转换:我如何转换的Python元组与dict

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"}]] 
+0

它看起来像你希望我们为你写一些代码。尽管许多用户愿意为遇险的编码人员编写代码,但他们通常只在海报已尝试自行解决问题时才提供帮助。证明这一努力的一个好方法是包含迄今为止编写的代码,示例输入(如果有的话),期望的输出和实际获得的输出(控制台输出,堆栈跟踪,编译器错误 - 无论是适用)。您提供的细节越多,您可能会收到的答案就越多。 – georg 2014-09-26 08:54:41

+0

我假设在你的输出中使用* tuples *的列表也可以;这使得可以使用'dict.items()'返回而不必将它们映射回列表。无论如何,在元组和列表之间进行转换是微不足道的。 – 2014-09-26 08:57:47

回答

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'})] 
+0

非常感谢你 – essp 2014-09-26 08:56:05

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)的时间。

+0

谢谢你的工作 – essp 2014-09-26 09:09:51