合并两个具有相同键的元组

时间:2014-11-23 19:43:08

标签: python list merge tuples

我有一个列表,其中包含每个条目的两个索引以及一个值。每个元组中的前两个元素分别是表中的行和列。第三项是单元格的值。

我想合并每个相同单元格的值。以下是数据结构的示例:

[
    (1, 2, 'R'),
    (1, 3, 'S'),
    (1, 2, 'S'),
    (2, 3, 'S'),
]

我需要合并具有匹配行/列对的项目,如下所示:

[
    (1, 2, 'RS'),
    (1, 3, 'S'),
    (2, 3, 'S'),
]

或:

[
    (1, 2, ('R', 'S')),
    (1, 3, ('S',)),
    (2, 3, ('S',)),
]

4 个答案:

答案 0 :(得分:3)

您可以使用itertools.groupby()

>>> from itertools import groupby
>>> l = [(1, 2, 'R'), (1, 3, 'S'), (1, 2, 'S'), (2, 3, 'S')]
>>> g_list=[list(g) for k, g in groupby(sorted(l),lambda x :x[0:2])]
>>> [(i[0],j[0],k) for i,j,k in [zip(*i) for i in g_list]]
[(1, 2, ('R', 'S')), (1, 3, ('S',)), (2, 3, ('S',))]

在这个片段中,我们首先需要使用sorted()函数对列表进行排序,根据这些元素对我们的tuplse进行排序,因此我们得到了这样的结果:

>>> sorted(l)
[(1, 2, 'R'), (1, 2, 'S'), (1, 3, 'S'), (2, 3, 'S')]

然后我们根据第一个tow元素(lambda x :x[0:2])对排序列表进行分组,这样我们就可以:

>>> g_list
[[(1, 2, 'R'), (1, 2, 'S')], [(1, 3, 'S')], [(2, 3, 'S')]]

所以现在我们有一个嵌套列表,其中包含相同的2个第一个元素,现在我们需要保留第1个和第2个元素中的一个以及两个(或更多)第3个元素,在这种情况下我们可以使用zip()函数会得到这样的结果:

>>> [zip(*i) for i in g_list]
[[(1, 1), (2, 2), ('R', 'S')], [(1,), (3,), ('S',)], [(2,), (3,), ('S',)]]

现在我们需要的是选择第一个和第二个元组的第0个元素以及第3个元素的整个元素:

(i[0],j[0],k) for i,j,k in ...

答案 1 :(得分:1)

这是应该有用的东西。如果您使用的是Python 3,请将.iteritems()方法调用更改为.items()(在该版本的Python中已经是迭代器)。

from collections import defaultdict

def merge_final_values(values):
    mergeddict = defaultdict(list)
    for group in values:
        mergeddict[group[:-1]].append(group[-1])
    return [(k + (tuple(v),) if len(v) > 1 else k + tuple(v))
                for k, v in mergeddict.iteritems()]

test = [(1, 2, 'R'), (1, 3, 'S'), (1, 2, 'S'), (2, 3, 'S')]

print(merge_final_values(test))

输出:

[(1, 2, ('R', 'S')), (1, 3, 'S'), (2, 3, 'S')]

如果要将合并的值连接成单个字符串,只需将函数的返回值更改为:

    return [(k + (''.join(v),)) for k, v in mergeddict.iteritems()]

你会得到这个输出:

[(1, 2, 'RS'), (1, 3, 'S'), (2, 3, 'S')]

答案 2 :(得分:0)

In [1]:     a=[(1, 2, 'R'), (1, 3, 'S'), (1, 2, 'S'), (2, 3, 'S')]
   ...:     b={}
   ...:     for i in a:
   ...:         try:
   ...:             b[i[0:2]] += (i[2],)
   ...:         except(KeyError):
   ...:             b[i[0:2]] = (i[2],)
   ...:     c=[k + (v,) for k, v in b.items()]
   ...:

In [2]: a
Out[2]: [(1, 2, 'R'), (1, 3, 'S'), (1, 2, 'S'), (2, 3, 'S')]

In [3]: b
Out[3]: {(1, 2): ('R', 'S'), (1, 3): ('S',), (2, 3): ('S',)}

In [4]: c
Out[4]: [(1, 2, ('R', 'S')), (1, 3, ('S',)), (2, 3, ('S',))]

答案 3 :(得分:0)

使用字典的另一种实现方式:

dct = {}

for *i, j in lst:
    dct.setdefault(tuple(i), list()).append(j)

[(*k, tuple(v)) for k, v in dct.items()]
# [(1, 2, ('R', 'S')), (1, 3, ('S',)), (2, 3, ('S',))]