Python. Подсчет количества чего-либо, что имеет одинаковое имя

247 просмотра
0
0 Комментариев

К примеру, есть список \ кортеж строк:


("2014-01-01 01:12:13 181",
 "2014-01-02 20:11:10 600",
 "2014-01-03 01:12:13 6009",
 "2014-01-03 12:13:55 200")


Нужно посчитать сумму значений, что отделены последним пробелом, по каждому дню (по значениям, отделенным первым пробелом), но как можно короче.

Я знаю, как это сделать, но мне кажется, можно использовать меньше строчек для этого. Mой вариант:

def total_cost(calls):
    cost = dict()
    for i in calls:
        i = i.split()
        cost[i[0]] = cost.get(i[0], 0) + int(i[2])
    return cost
 
print(total_cost(("2014-01-01 01:12:13 181",
                  "2014-01-02 20:11:10 600",
                  "2014-01-03 01:12:13 6009",
                  "2014-01-03 12:13:55 200")))

Итак, возможно ли короче?


Добавить комментарий

2 Answers

Python Опубликовано 09.12.2018
0

Можно так поробовать:

from itertools import groupby
 
res = [(a,sum(map(lambda x: int(x.rsplit(maxsplit=1)[-1]), b)))
       for a,b in groupby(lst, lambda x: x.split()[0])]

Результат:

In [57]: print(res)
[('2014-01-01', 181), ('2014-01-02', 600), ('2014-01-03', 6209)]


или еще чуть короче:

res = [(a,sum(map(lambda x: int(x.split()[-1]), b)))
       for a,b in groupby(lst, lambda x: x.split()[0])]


Вот гораздо более элегантное решение от @YuriM1983:

from collections import Counter
 
a = ("2014-01-01 01:12:13 181", "2014-01-02 20:11:10 600",
     "2014-01-03 01:12:13 6009",  "2014-01-03 12:13:55 200")
 
cost = sum((Counter({x.split()[0]: int(x.split()[-1])}) for x in a), Counter())

Результат:

In [68]: print(cost)
Counter({'2014-01-03': 6209, '2014-01-02': 600, '2014-01-01': 181})
 
In [69]: print(dict(cost))
{'2014-01-01': 181, '2014-01-02': 600, '2014-01-03': 6209}

Добавить комментарий
0

Для подсчёта, как часто элементы в коллекции встречаются, удобно collections.Counter использовать:

from collections import Counter
 
counter = Counter()
for line in calls:
    date, _, cost = line.rpartition(' ')
    counter[date] += int(cost)

Не стоит пытаться умять код в одну строчку, если это делает код менее читаемым. Но если хочется любой ценой получить однострочник:

>>> {date: int(cost) for line in calls for date, _, cost in [line.rpartition(' ')]}
{'2014-01-01 01:12:13': 181,
 '2014-01-02 20:11:10': 600,
 '2014-01-03 01:12:13': 6009,
 '2014-01-03 12:13:55': 200}

это предполагает что даты не повторяются.

Добавить комментарий
Напишите свой ответ на данный вопрос.
Scroll Up