2

Поэтому у меня есть данные, структурированные в вложенном списке как такCondenseing/преобразования вложенного списка с помощью словаря понимания

data = [['A', '1'], ['B', '2'], ['C', '3'], ['A', '-2'], ['B', '4'], ['C', '1'], ['A', '2'], ['B', '1'], ['C', '-5']] 

и я пытаюсь преобразовать его в выходной сигнал, который выглядит как этот

{'A': 1, 'C': -1, 'B': 7} 

В целом суммируйте все A, B и C, поместите вывод в качестве словаря.

Я написал этот код, который дает правильный ответ

playerSum = {} 
for ele in data: 
    if ele[0] not in playerSum: 
     playerSum[ele[0]] = int(ele[1]) 
    else: 
     playerSum[ele[0]] += int(ele[1]) 

Однако я пытаюсь преобразовать блок кода выше в словаре понимания. В основном я понимаю, как это сделать, но я не понимаю, как написать + = как понимание словаря. Любое руководство по структуре было бы здорово.

До сих пор у меня есть этот

playerSum = {ele[0]: int(ele[1]) if ele[0] not in playerSum else playerSum[ele[0]] += int(ele[1]) for ele in data} 

Edit: Так @achampion был в состоянии решить. Благодаря!

{key: sum(int(v) for k, v in data if k==key) for key in set(k for k, _ in data)} 
+0

Если вы показываете код, вы должны добавить языковой тег. – crashmstr

+0

Только что, забыл, так как я писал все это. – nothisispatrick11

+0

@ nothisispatrick11, просто невозможно сделать то, что вы пытаетесь, все, что вы можете сделать, это сделать более эффективный подход. –

ответ

0

Лучший способ является наиболее очевидным способом

from collections import defaultdict 
playerSum = defaultdict(int) 

for key, value in data: 
    playerSum[key] += int(value) 
0

Это не можно использовать Dict понимание, как ваши ценности будут перезаписаны, то ДИКТ не получает создан, пока понимание не является так что даже если вы не можете ничего + =. Как бы то ни было, если у вас нет playerSum = {}, где-то ваш код будет ошибочным с помощью NameError, если вы просто переписываете имя в результат вашего dict comp, поэтому playerSum = {} в основном ничего не делает.

Единственный способ сделать то, что вы хотите, - это вдоль линии вашего собственного решения. Для более эффективного подхода можно распаковывать подсписков и бросил второй элемент в целое, суммируя значения с помощью collections.defaultdict:

from collections import defaultdict 

d = defaultdict(int) 

for a,b in data: 
    d[a] += int(b) 

print(d) 
defaultdict(<type 'int'>, {'A': 1, 'C': -1, 'B': 7}) 

Или с помощью обычного Dict:

d = {} 

for a, b in data: 
    d[a] = d.get(a,0) + int(b) 

print(d) 
{'A': 1, 'C': -1, 'B': 7} 
0

Я сделал это как вы спросили.

dict ([(key, sum(int(elem[1]) for elem in data if elem[0]==key)) for key in [id for id in set([elem[0] for elem in data])] ]) 

От внешнего к внутреннему:

  • Построить набор идентификаторов, используемый в списке.

  • Для каждого идентификатора создайте список связанных значений.

  • Составьте список.

  • Исчислите (введите) идентификатор и сумму в виде пары.

  • Включите этот список кортежей в словарь.

Тест:

data = [['A', '1'], ['B', '2'], ['C', '3'], 
     ['A', '-2'], ['B', '4'], ['C', '1'], 
     ['A', '2'], ['B', '1'], ['C', '-5']] 
playerSum = dict ([(key, sum(int(elem[1]) for elem in data if elem[0]==key)) 
        for key in [id for id in set([elem[0] for elem in data])] ]) 
print data 
print playerSum 

Результат:

[['A', '1'], ['B', '2'], ['C', '3'], ['A', '-2'], ['B', '4'], ['C', '1'], ['A', '2'], ['B', '1'], ['C', '-5']] 
{'A': 1, 'C': -1, 'B': 7} 
+0

Это невероятно неэффективно, правильный ответ: невозможно сделать то, что OP хочет использовать обычным dict Понимание –

+2

Не 'для ключа в [id для id в наборе ([...])]' just 'для ключа в set (...)' без ненужных конструкций списков? Или упрощено: '{key: sum (int (v) для k, v в данных, если k == key) для ключа в наборе (k для k, _ в данных)}' – AChampion

+0

@achampion, ваше решение намного чище, не говоря уже о фактическом понимании словаря. Благодаря! – Prune

2

Это не практично, чтобы сделать это как понимание.
Подобно тому, как упражнение, которое вы можете использовать сопрограмму сделать подсчет для вас, но вы эффективно создать словарь дважды:

from collections import defaultdict 
def count(): 
    cache = defaultdict(int) 
    k, v = yield 
    while True: 
     cache[k] += v 
     k, v = yield cache[k] 

counter = count() # Create coroutine 
next(counter)  # Prime coroutine 

data = [['A', '1'], ['B', '2'], ['C', '3'], ['A', '-2'], ['B', '4'], 
     ['C', '1'], ['A', '2'], ['B', '1'], ['C', '-5']] 

{k: counter.send((k, int(v))) for k, v in data} # Meets the challenge :) 

Результат:

{'A': 1, 'B': 7, 'C': -1} 

Или действительно некрасиво один- вкладыш, который не нуждается в сопрограмму и не является квадратичным (не понимание):

>>> reduce(lambda d, (k,v): d.__setitem__(k, d.get(k,0)+int(v)) or d, data, {}) # Py2.7 
{'A': 1, 'B': 7, 'C': -1} 

и плавник а также очень неэффективное, но истинное понимание dict на основе @Prune:

>>> {key: sum(int(v) for k, v in data if k==key) for key in set(k for k, _ in data)} 
{'A': 1, 'B': 7, 'C': -1}