2014-09-26 58 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