繁体   English   中英

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

[英]merge two tuples with same key

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

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

[
    (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',)),
]

您可以使用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()函数对我们的列表进行sorted() ,该函数根据这些元素对我们的元组进行排序,所以我们得到了这个结果:

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

然后我们根据第一个元素( 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 ...

这是应该起作用的东西。 如果您使用的是 Python 3,请将.iteritems()方法调用更改为.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')]
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',))]

另一个使用字典的实现:

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',))]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM