[英]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.