Найти - Пользователи
Полная версия: Что то типа GROUP BY из SQL для списка словарей?
Начало » Python для новичков » Что то типа GROUP BY из SQL для списка словарей?
1
Bujhm666
Есть примерно такая структура:
list = [{'key':1, 'a':100, 'b':50, 'c':80},
{'key':2, 'a':200, 'b':60, 'c':70},
{'key':2, 'a':300, 'b':70, 'c':60},
{'key':3, 'a':400, 'b':80, 'c':50},
{'key':4, 'a':500, 'b':90, 'c':40},
{'key':4, 'a':600, 'b':40, 'c':30}]
Из нее надо получить следующее:
list = [{'key':1, 'a':100, 'b':50, 'c':80},
{'key':2, 'a':500, 'b':130, 'c':130},
{'key':3, 'a':400, 'b':80, 'c':50},
{'key':4, 'a':1100, 'b':130, 'c':70}]
Т.е. просуммировать значения в словарях с одинаковым ‘key’.
Что то не пойму как это реализовать.
Studentik
list = [
{'key':1, 'a':100, 'b':50, 'c':80},
{'key':2, 'a':200, 'b':60, 'c':70},
{'key':2, 'a':300, 'b':70, 'c':60},
{'key':3, 'a':400, 'b':80, 'c':50},
{'key':4, 'a':500, 'b':90, 'c':40},
{'key':4, 'a':600, 'b':40, 'c':30}]

conn = sqlite3.connect(":memory:")

conn.execute("create table list (key, a, b)")
conn.executemany("insert into list (key, a, b) values (:key, :a, :b)",list)
cur = conn.execute("select key, SUM(a), SUM(b) from list group by key")
print(cur.fetchall())
Bujhm666
Спасибо. Но меня интересовало. как это сделать на голом питоне, без использования SQL, и не привлекая сторонние БД.
Studentik
Голый питон - это без использования стандартной библиотеки???
o7412369815963
вот такой изврат получился
lis = [{'key':1, 'a':100, 'b':50, 'c':80},
{'key':2, 'a':200, 'b':60, 'c':70},
{'key':2, 'a':300, 'b':70, 'c':60},
{'key':3, 'a':400, 'b':80, 'c':50},
{'key':4, 'a':500, 'b':90, 'c':40},
{'key':4, 'a':600, 'b':40, 'c':30}]

from itertools import groupby

res = []
for k,l in groupby(lis, lambda x:x['key']):
l = list(l)
if len(l) > 1:
l = dict( [ reduce(lambda a,b: ( a[0],a[1]+b[1]) , x) for x in map(None, *[x.items() for x in l]) ] )
l.update({ 'key':k })
else: l = l[0]
res.append(l)

print res
если ключи не будут идти по порядку то их нужно будет сначала отсортировать
doza_and
В этом варианте несколько модифицирована структура данных
li = [{'key':1, 'a':100, 'b':50, 'c':80},
{'key':2, 'a':200, 'b':60, 'c':70},
{'key':2, 'a':300, 'b':70, 'c':60},
{'key':3, 'a':400, 'b':80, 'c':50},
{'key':4, 'a':500, 'b':90, 'c':40},
{'key':4, 'a':600, 'b':40, 'c':30}]

listOfDict=[[rec.pop('key'),rec] for rec in li]

def dictadd(a,b):
for k,v in b.iteritems():
vv=a.get(k,0)
a[k]=vv+v

res={}
for key,val in listOfDict:
vv=res.get(key,{})
dictadd(vv,val)
res[key]=vv
Bujhm666
Всем большое спасибо, буду экспериментировать в плане скорости обработки. Это я тут 5 строчек набросал, а у меня такой бодяги на 50 мегабайт будет.
Александр Кошелев
Bujhm666
Всем большое спасибо, буду экспериментировать в плане скорости обработки. Это я тут 5 строчек набросал, а у меня такой бодяги на 50 мегабайт будет.
Тогда выбор в сторону SQLite очевиден.
Bujhm666
Да я не против SQLITE, просто хочу проверить несколько вариантов. Я эти данные тяну из dbf-файлов, что уже и так дает приличные тормоза и ладно, если бы просто перегнать структуру в sqllite (mysql, postgrees и т.д.) и с ней работать, но нужно использовать именно dbf, а т.к. данные постоянно меняются приходится это делать при каждом старте программы.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB