如何转换以下元组列表:
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 :(得分: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'})]