Устранить дубли и суммировать соответствующие термины в списках - PullRequest
1 голос
/ 03 ноября 2010

Учитывая эти 2 списка

L2 = [A,B,C,D,A,B]
L3 = [3,2,1,2,2,1]

Я хочу получить

L2_WANTED = [A,B,C,D]
L3_WANTED = [5,3,1,2]

Списки всегда упорядочены, и один и тот же размер и элементы соответствуют парам значений ключа, например, A: 3, B: 2 и т. Д.

Цель состоит в том, чтобы устранить дуплексы в L2 и суммировать соответствующие слагаемые в L3, чтобы получить новый список с совпадающими парами. Это необходимо для того, чтобы сохранить текущий список элементов по мере их добавления в списки.

Я пытался написать функцию с index, но она стала уродливой. Я проверил itertools, но не смог найти ничего, что имеет отношение; Я посмотрел на starmap(), но не смог заставить его работать. Возможно, это можно сделать и с помощью понимания списка. Я был бы признателен за любые подсказки или указания о том, как добиться этого наиболее простым способом. Спасибо.

РЕДАКТИРОВАТЬ

@ SimonC:

>>> l2_sum = {}
>>> for i in range(0, len(L2)):
        key = L2[i]
        num = L3[i]
        l2_sum[key] = l2_sum.get(key, 0) + num


>>> l2_sum
{'A': 5, 'C': 1, 'B': 3, 'D': 2}
>>>

Как это устраняет дубликаты и добавляет числа? Можете ли вы дать подсказку? Благодарю.

Ответы [ 3 ]

2 голосов
/ 04 ноября 2010

Я думаю, использование zip - хороший способ объединить списки.Часть dict.update выполнит суммирование, так как я получаю предыдущее значение и обновляю его:

foo = dict()
for x, y in zip(['A', 'B', 'C', 'D', 'A', 'B'],
                [3, 2, 1, 2, 2, 1]):
    foo[x] = y + foo.get(x, 0)

print foo

Выходы: {'A': 5, 'C': 1, 'B': 3, 'D': 2}

Редактировать:

В то время как вышехорошо, я бы также рассмотрел использование itertools.izip , которое позволяет вам делать zip при создании словаря.Таким образом, вы сэкономите на памяти.Все, что вам нужно сделать, это заменить zip на itertools.izip после импорта iterools

2 голосов
/ 03 ноября 2010

Я уверен, что там есть более элегантный ответ, и он пришел бы в ответах.

Но для некоторых простых ответов:

L2 = ['A','B','C','D','A','B']
L3 = [3,2,1,2,2,1]

L4 = zip(L2, L3)

L5 = []
L6 = []
def freduce(l):
    for x, y in l:
        print x , y
        if x in L5:
            k = L5.index(x)
            L6[k] += y
        else:
            L5.append(x)
            L6.append(y)

freduce(L4)  
print L5
print L6

Вывод:

['A', 'B', 'C', 'D']
[5, 3, 1, 2]

[Отредактированный ответ для понимания второй реализации]

>>> L3 = [3,2,1,2,2,1]
>>> L2 = ['A','B','C','D','A','B']
>>> range(0, len(L2))
[0, 1, 2, 3, 4, 5]
>>> 

Следовательно, для i в диапазоне (0, len (L2)): ... i становится индексом

Использование этого индексаВы можете извлечь информацию из L3 и L2, выполнив:

key = L2[i]
num = L3[i]

Затем вы добавите информацию в dict

l2_sum[key] = l2_sum.get(key, 0) + num

Здесь l2_sum.get (key, 0) возвращает 0, еслиключ отсутствует, иначе текущее значение.

Надеюсь, оно достаточно понятно.

1 голос
/ 03 ноября 2010

Это будет сделано, но согласно pyfunc, есть лучшие способы:

l2_sum = {}
for i in range(0,len(L2)):
    key = L2[i]
    num = L3[i]
    l2_sum[key] = l2_sum.get(key, 0) + num

L2_WANTED = sorted(l2_sum.keys())
L3_WANTED = [l2_sum[key] for key in L2_WANTED]
...