Python самый простой способ суммировать пересечение списка списка кортежей
скажем, у меня есть следующие два списка кортежей
myList = [(1, 7), (3, 3), (5, 9)]
otherList = [(2, 4), (3, 5), (5, 2), (7, 8)]
returns => [(1, 7), (2, 4), (3, 8), (5, 11), (7, 8)]
Я хотел бы разработать операцию слияния, которая объединяет эти два списка, проверяя любые пересечения на первом элементе кортежа, если есть пересечения, добавьте вторые элементы каждого кортежа в вопросе (объединить два). После операции я хотел бы отсортировать на основе первого элемента.
Я также отправляю это, потому что я думаю, что это довольно распространенная проблема, которая имеет явный решение, но я чувствую, что там может быть очень подходящие для Python решения этого вопроса ;)
4 ответов
используйте словарь для результата:
result = {}
for k, v in my_list + other_list:
result[k] = result.get(k, 0) + v
Если вам нужен список кортежей, вы можете получить его через result.items()
. Результирующий список будет в произвольном порядке, но при желании его можно отсортировать.
(обратите внимание, что я переименовал ваши списки в соответствии с соглашениями стиля Python.)
использовать defaultdict:
from collections import defaultdict
results_dict = defaultdict(int)
results_dict.update(my_list)
for a, b in other_list:
results_dict[a] += b
results = sorted(results_dict.items())
Примечание: при сортировке последовательностей,sorted
сортировка по первому элементу в последовательности. Если первые элементы совпадают, то сравнивается второй элемент. Вы можете дать sorted
функция для сортировки, используя key
ключевое слово аргумент:
results = sorted(results_dict.items(), key=lambda x: x[1]) #sort by the 2nd item
или
results = sorted(results_dict.items(), key=lambda x: abs(x[0])) #sort by absolute value
метод с использованием itertools:
>>> myList = [(1, 7), (3, 3), (5, 9)]
>>> otherList = [(2, 4), (3, 5), (5, 2), (7, 8)]
>>> import itertools
>>> merged = []
>>> for k, g in itertools.groupby(sorted(myList + otherList), lambda e: e[0]):
... merged.append((k, sum(e[1] for e in g)))
...
>>> merged
[(1, 7), (2, 4), (3, 8), (5, 11), (7, 8)]
этот первый объединяет два списка вместе и сортирует его. itertools.метода groupBy возвращает элементы Объединенного списка, сгруппированные по первому элементу кортежа, поэтому он просто суммирует их и помещает в объединенный список.
>>> [(k, sum(v for x,v in myList + otherList if k == x)) for k in dict(myList + otherList).keys()]
[(1, 7), (2, 4), (3, 8), (5, 11), (7, 8)]
>>>
проверено для обоих Python2.7 и 3.2dict(myList + otherList).keys()
возвращает итерацию, содержащую набор ключей для объединенных списковsum(...)
принимает "k", чтобы снова пройти через Объединенный список и добавить элементы кортежа "v", где k == x
... но дополнительный цикл добавляет накладные расходы на обработку. Используя явный словарь, предложенные Свен Марнах избегает его.