我有一个名为元组的二维列表(假设每个元组都有N个值),我想将它们解压缩到N个不同的二维列表中,其中每个解包的二维列表完全由一个单独组成原始列表中的属性。例如,如果我有这个2-D列表:
>>> combo = namedtuple('combo', 'i, f, s')
>>> combo_mat = [[combo(i + 3*j, float(i + 3*j), str(i + 3*j)) for i in range(3)]
for j in range(3)]
>>> combo_mat
[[combo(i=0, f=0.0, s='0'), combo(i=1, f=1.0, s='1'), combo(i=2, f=2.0, s='2')],
[combo(i=3, f=3.0, s='3'), combo(i=4, f=4.0, s='4'), combo(i=5, f=5.0, s='5')],
[combo(i=6, f=6.0, s='6'), combo(i=7, f=7.0, s='7'), combo(i=8, f=8.0, s='8')]]
我希望3个结果是:
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]
[[0.0, 1.0, 2.0],
[3.0, 4.0, 5.0],
[6.0, 7.0, 8.0]]
[['0', '1', '2'],
['3', '4', '5'],
['6', '7', '8']]
如果我只有一个一维的元组列表,我会使用zip(*mylist)
,如:
>>> zip(*[combo(i=0, f=0.0, s='0'), combo(i=1, f=1.0, s='1'), combo(i=2, f=2.0, s='2')])
[(0, 1, 2), (0.0, 1.0, 2.0), ('0', '1', '2')]
我可以通过嵌套来扩展这种情况:
>>> zip(*[zip(*combs) for combs in combo_mat])
[((0, 1, 2),
(3, 4, 5),
(6, 7, 8)),
((0.0, 1.0, 2.0),
(3.0, 4.0, 5.0),
(6.0, 7.0, 8.0)),
(('0', '1', '2'),
('3', '4', '5'),
('6', '7', '8'))]
但是这并没有给我我想要的列表,并且嵌套的解包zip(*)
函数是不可读的。任何人都有更多pythonic解决方案的想法?如果您可以在最终结果中的某处处理元组属性的名称,则可以获得奖励积分。
实际上,现在我想到它,如果我可以有一个将元组属性的名称映射到其各自矩阵的dict,它将是理想,如:
{'i': [[0, 1, 2],
[3, 4, 5],
[6, 7, 8]],
'f': [[0.0, 1.0, 2.0],
[3.0, 4.0, 5.0],
[6.0, 7.0, 8.0]]
's': [['0', '1', '2'],
['3', '4', '5'],
['6', '7', '8']]}
答案 0 :(得分:3)
救援的功能性编程?它本质上是一个嵌套拉链的清洁版本:
def fmap_element(f, el):
return f(el)
def fmap_list(f, l):
return [fmap_element(f, el) for el in l)]
def fmap_lol(f, lol):
return [fmap_list(f,l) for l in lol]
def split_nt_lol(nt_lol):
return dict((name, fmap_lol(lambda nt: getattr(nt, name), nt_lol))
for name in nt_lol[0][0]._fields)
用法:
>>> split_nt_lol(combo_mat)
{'i': [[0, 1, 2], [3, 4, 5], [6, 7, 8]],
's': [['0', '1', '2'], ['3', '4', '5'], ['6', '7', '8']],
'f': [[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]}
答案 1 :(得分:2)
matrices = {}
for num, name in enumerate(combo._fields):
matrix = []
for i in combo_mat:
row = []
for j in i:
row.append(j[num])
matrix.append(row)
matrices[name] = matrix
答案 2 :(得分:1)
这比嵌套的zip(*)
函数更具可读性,但它可以完成工作:
>>> dict((key, [[c._asdict()[key] for c in combos] for combos in combo_mat])
for key in ['i', 'f', 's'])
{'i': [[0, 1, 2], [3, 4, 5], [6, 7, 8]],
's': [['0', '1', '2'], ['3', '4', '5'], ['6', '7', '8']],
'f': [[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]}
我想你可以让它更容易阅读:
def get_mat(combo_mat, key):
return [[c._asdict()[key] for c in combos] for combos in combo_mat]
def get_mat_dict(combo_mat, keys):
return dict((key, get_mat(combo_mat, key)) for key in keys)
答案 3 :(得分:0)
这可以通过使用transpose()转换数组来实现。
参考: http://www.astro.ufl.edu/~warner/prog/python.html(搜索“转置”一词)