【问题标题】:merge two tuples with same key合并两个具有相同键的元组
【发布时间】:2015-01-21 11:51:14
【问题描述】:

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

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

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

【问题讨论】:

  • 对于 myList 中的成员:out=[] for i in range(0,len(myList)): for j in range(0,len(myList)): if (member[0]. myList[i]==member[0].myList[j]) 和 (member[1].myList[i]==member[1].mylist[j]): newlist=[(member[0],member [1],(member[2].myList[i],member[2].myList[j]))] out.append[newlist] else: out.append(member) print(out) #我很基础在 python 中,可能我在这段代码中有很多问题。我会感谢你的帮助

标签: python list merge tuples


【解决方案1】:

你可以使用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',))]

在这个 sn-p 中,我们首先需要使用 sorted() 函数对列表进行排序,该函数根据这些元素对我们的 tuplse 进行排序,所以我们有这个结果:

>>> 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 ...

【讨论】:

  • 非常感谢!对不起,我的代码格式不正确。我当时不知道格式规则!
【解决方案2】:

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

【讨论】:

  • 非常感谢。只是一个小提示: dict.iteritems() 在 python 3 中被 dict.items() 取代。
【解决方案3】:
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',))]

【讨论】:

    【解决方案4】:

    另一个使用字典的实现:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      相关资源
      最近更新 更多