Python вычисляет текущую сумму значений в одной строке

115
12

Я пытаюсь обрабатывать такие данные:


some_data = [
{'value': 2, 'date':'2016-02-06'},
{'value': 1, 'date':'2016-02-07'},
{'value': 5, 'date':'2016-02-08'},
{'value': 3, 'date':'2016-02-09'},
{'value': 1, 'date':'2016-02-10'},
]

Таким образом, он создает список со значениями, обновленными как текущая сумма. Теперь я делаю это с помощью многострочного цикла:


def values_incremented(some_data):
temp_sum = 0
result = []
for element in some_data:
temp_sum += element['value']
result.append({'value': temp_sum, 'date': element['date']})
return result

Как сделать цикл однострочным, чтобы я получил:


return [{'value': somehow_incremented, 'date': element['date']} for element in some_data]

спросил(а) 2021-01-28T01:02:56+03:00 2 месяца, 2 недели назад
1
Решение
115

Вы можете написать себе функцию накопительного генератора. Используйте send для отправки значений в генератор и получения новой суммы.


def accumulator(n=0):
while True:
n += yield n

acc = accumulator(0)
acc.send(None)

res = [{'value': acc.send(element['value']), 'date': element['date']} for element in some_data]

В результате res есть


[{'value': 2, 'date': '2016-02-06'}, 
{'value': 3, 'date': '2016-02-07'},
{'value': 8, 'date': '2016-02-08'},
{'value': 11, 'date': '2016-02-09'},
{'value': 12, 'date': '2016-02-10'}]

ответил(а) 2021-01-28T01:02:56+03:00 2 месяца, 2 недели назад
87

Я бы не рекомендовал ничего делать, ваш код в порядке. Держите его читаемым.


При этом здесь подход:

def values_incremented(some_data):
return [{'value': current_sum, 'date': element['date']}
for element, current_sum
in zip(some_data,
reduce(lambda x, y: [y['value']] if not x else x + [x[-1] + y['value']], some_data, []))]

ответил(а) 2021-01-28T01:02:56+03:00 2 месяца, 2 недели назад
62

Здесь один лайнер, который работает в линейном времени:


reduce(lambda (c,s), a: (c + [{'value':s+a['value'], 'date':a['date']}], s+a['value']), some_data,([],0))[0]

>>> [{'date': '2016-02-06', 'value': 2},
{'date': '2016-02-07', 'value': 3},
{'date': '2016-02-08', 'value': 8},
{'date': '2016-02-09', 'value': 11},
{'date': '2016-02-10', 'value': 12}]


Вы должны посмотреть на другой текущий общий вопрос для более простой версии той же проблемы.

ответил(а) 2021-01-28T01:02:56+03:00 2 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема