简体   繁体   English

如何合并元组列表

[英]How to merge list of tuples

I have two lists of tuples like this:我有两个这样的元组列表:

x1 = [('A', 3), ('B', 4), ('C', 5)]

x2 = [('B', 4), ('C', 5), ('D', 6)]

I want to merge the two lists as a new one x3 so that the values in the list are added.我想将两个列表合并为一个新的 x3,以便添加列表中的值。

x3 = [('A', 3), ('B', 8), ('C', 10),('D',6)]

Could you please show me how I can do this?你能告诉我如何做到这一点吗?

You can create a dictionary and then loop over the values in each list, and either adding to the current value for each key in the dictionary, or setting the value equal to the current value if no value currently exists.您可以创建一个字典,然后遍历每个列表中的值,然后添加到字典中每个键的当前值,或者如果当前不存在任何值,则将该值设置为等于当前值。 Afterwards you can cast back to a list.之后,您可以转换回列表。

For example:例如:

full_dict = {}
for x in [x1, x2]:
    for key, value in x:
        full_dict[key] = full_dict.get(key, 0) + value # add to the current value, if none found then use 0 as current value

x3 = list(full_dict.items())

Result for x3 : x3结果:

[('A', 3), ('B', 8), ('C', 10), ('D', 6)]

Since you tag pandas既然你标记了pandas

df1,df2=pd.DataFrame(x1),pd.DataFrame(x2)
pd.concat([df1,df2]).groupby(0,as_index=False).sum().apply(tuple,1).tolist()
[('A', 3), ('B', 8), ('C', 10), ('D', 6)]

Use collections.Counter使用collections.Counter

>>> x1 = [('A', 3), ('B', 4), ('C', 5)]
>>> x2 = [('B', 4), ('C', 5), ('D', 6)]
>>> from collections import Counter
>>> c1 = Counter(dict(x1))
>>> c2 = Counter(dict(x2))
>>> c3 = c1 + c2   
>>> c3.items()
dict_items([('A', 3), ('B', 8), ('C', 10), ('D', 6)])

Just create a Counter for each list, you can do this by turning the list of tuples into an intermediate dict.只需为每个列表创建一个Counter ,您可以通过将元组列表转换为中间字典来实现。 Then just add the Counters.然后只需添加计数器。

To get the list back just call the items method of the counter.要取回列表,只需调用计数器的 items 方法。 Technically what is returned is a dict_items object, if it really matters that its a list then just call list on c3.items() ie list(c3.items()) .从技术上讲,返回的是一个dict_items对象,如果它真的很重要它是一个list那么只需在c3.items()上调用 list ,即list(c3.items())

An alternative 1 liner using groupby and heapq.merge.使用 groupby 和 heapq.merge 的替代 1 班轮。

from heapq import merge
from itertools import groupby
from operator import itemgetter

x1 = [('A', 3), ('B', 4), ('C', 5)]
x2 = [('B', 4), ('C', 5), ('D', 6)]

result = [(a, sum(t[1] for t in b)) for a, b in groupby(merge(x1, x2), key=itemgetter(0))]
print(result)

heapq.merge is roughly equivalent to sorted(itertools.chain(*iterables)) . heapq.merge大致相当于sorted(itertools.chain(*iterables)) It basically provides a sorted, merged list of the tuples, ready to be fed to groupby.它基本上提供了一个排序的、合并的元组列表,准备好提供给 groupby。

I think the following code works我认为以下代码有效

dict_x1=dict(x1)
for item in x2:
  if item[0] in dictx1:
    dictx1[item[0]] += item[1]
  else:
    dictx1[item[0] = item[1]

You can also solve this with itertools你也可以用itertools解决这个问题

from itertools import groupby
from operator import itemgetter

first = itemgetter(0)
second = itemgetter(1)
res = {}
data = x1 + x2

for _, g in groupby(sorted(data, key=first), key=first):
    group = list(g)
    k = first(first(group))
    v = sum(second(gr) for gr in group)
    res[k] = v

print(sorted(res.items(), key=first))

[('A', 3), ('B', 8), ('C', 10), ('D', 6)]

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

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