2016-08-02 2 views
1

У меня есть два двумерных списка. Каждый элемент list содержит list с идентификатором строки и целым числом. Я хочу вычесть целые числа друг от друга, где совпадает идентификатор строки.Расчет 2d-списка

Список 1:

list1 = [['ID_001',1000],['ID_002',2000],['ID_003',3000]] 

Список 2:

list2 = [['ID_001',500],['ID_003',1000],['ID_002',1000]] 

Я хочу закончить с

difference = [['ID_001',500],['ID_002',1000],['ID_003',2000]] 

Обратите внимание, что элементы не обязательно в том же порядке, в оба списка. Оба списка будут иметь одинаковую длину, и в обоих списках есть целое число, соответствующее каждому идентификатору.

Мне также хотелось бы, чтобы это было сделано эффективно, так как в обоих списках будут тысячи записей.

ответ

2
from collections import defaultdict 

diffs = defaultdict(int) 
list1 = [['ID_001',1000],['ID_002',2000],['ID_003',3000]] 
list2 = [['ID_001',500],['ID_003',1000],['ID_002',1000]] 
for pair in list1: 
    diffs[pair[0]] = pair[1] 
for pair in list2: 
    diffs[pair[0]] -= pair[1] 

differences = [[k,abs(v)] for k,v in diffs.items()] 
print(differences) 

Мне было любопытно, поэтому я провел несколько минут, сравнивая свой ответ с Джим. Кажется, что они работают примерно в одно и то же время. Тем не менее, вы можете сократить время выполнения шахты в два раза, если вы хотите принять вывод в качестве словаря.

Его, конечно, больше Pythonic, если это важно для вас.

+0

Работал отлично. Мне нужно, чтобы результаты возвращались в виде списка списков, а решение Jims возвращало список кортежей. Благодаря! – Cellydy

+1

Его решение можно изменить, чтобы вернуть список списков путем обертывания 'i [0], abs (i [1] - j [1])' в '[]', а не '()' – dashiell

2

Вы могли бы добиться этого с помощью список понимание:

diff = [(i[0], abs(i[1] - j[1])) for i,j in zip(sorted(list1), sorted(list2))] 

Этот первый сортирует списки с sorted для того, чтобы быть похож (не с list.sort() который сортирует на месте), а затем, он создает кортежи, содержащие каждую запись в списках ['ID_001', 1000], ['ID_001', 500], путем подачи отсортированных списков до zip.

Наконец:

(i[0], abs(i[1] - j[1])) 

возвращает i[0] с указанием ID для каждой записи и abs(i[1] - j[1]) вычисляет их абсолютное значение. В итоговый результат списка добавляется кортеж (), обратите внимание на круглые скобки вокруг них).


В общем, sortedможет замедлить Вас, если у вас есть большое количество данных, но это зависит от того, как неорганизованный данные от того, что я знаю.

Кроме этого, zip создает итератор, поэтому память разумна, это не влияет на вас. Скоростные мудрые, списки comps, как правило, достаточно эффективны, и в большинстве случаев ваши лучшие варианты.