import random, string
from collections import Counter, defaultdict
import operator
from itertools import groupby, chain
from timeit import timeit
def rndstr(len):
return ''.join(random.choice(string.letters) for i in xrange(len))
def rnditem():
return (rndstr(20), random.randint(1, 1000))
a=[("13.5",100)]
b=[("14.5",100), ("15.5", 100)]
c=[("15.5",100), ("16.5", 100)]
input=[a,b,c]
def kos(input):
return reduce(operator.add, (Counter(dict(x)) for x in input))
def kos2(input):
def u(a,b):
a.update(b)
return a
return reduce(u, (Counter(dict(x)) for x in input))
def initial(input):
output=defaultdict(int)
for d in input:
for item in d:
output[item[0]]+=item[1]
return dict(output)
def BigYellowCactus(input):
input = sorted(chain(*input), key=lambda x: x[0])
output = {}
for k, g in groupby(input, key=lambda x: x[0]):
output[k] = sum(x[1] for x in g)
return output
def merge_with(d1, d2, fn=lambda x, y: x + y):
res = d1.copy()
for key, val in d2.iteritems():
try:
res[key] = fn(res[key], val)
except KeyError:
res[key] = val
return res
def astynax(input):
return reduce(merge_with, map(dict,input))
dim = 80
input = [[rnditem() for i in xrange(dim)] for j in xrange(dim)]
results = [(k.func_name, timeit(lambda: k(input), number=3)) for k in (kos, kos2, initial, BigYellowCactus, astynax)]
results.sort(key=operator.itemgetter(1))
print '\n'.join(str.format('{:20}{}', *x) for x in results)
aW1wb3J0IHJhbmRvbSwgc3RyaW5nCmZyb20gY29sbGVjdGlvbnMgaW1wb3J0IENvdW50ZXIsIGRlZmF1bHRkaWN0CmltcG9ydCBvcGVyYXRvcgpmcm9tIGl0ZXJ0b29scyBpbXBvcnQgZ3JvdXBieSwgY2hhaW4KZnJvbSB0aW1laXQgaW1wb3J0IHRpbWVpdAoKCmRlZiBybmRzdHIobGVuKToKICAgIHJldHVybiAnJy5qb2luKHJhbmRvbS5jaG9pY2Uoc3RyaW5nLmxldHRlcnMpIGZvciBpIGluIHhyYW5nZShsZW4pKQoKZGVmIHJuZGl0ZW0oKToKICAgIHJldHVybiAocm5kc3RyKDIwKSwgcmFuZG9tLnJhbmRpbnQoMSwgMTAwMCkpCgphPVsoIjEzLjUiLDEwMCldCmI9WygiMTQuNSIsMTAwKSwgKCIxNS41IiwgMTAwKV0KYz1bKCIxNS41IiwxMDApLCAoIjE2LjUiLCAxMDApXQppbnB1dD1bYSxiLGNdCgoKZGVmIGtvcyhpbnB1dCk6CiAgICByZXR1cm4gcmVkdWNlKG9wZXJhdG9yLmFkZCwgKENvdW50ZXIoZGljdCh4KSkgZm9yIHggaW4gaW5wdXQpKQoKZGVmIGtvczIoaW5wdXQpOgogICAgZGVmIHUoYSxiKToKICAgICAgICBhLnVwZGF0ZShiKQogICAgICAgIHJldHVybiBhCiAgICByZXR1cm4gcmVkdWNlKHUsIChDb3VudGVyKGRpY3QoeCkpIGZvciB4IGluIGlucHV0KSkKCmRlZiBpbml0aWFsKGlucHV0KToKICAgIG91dHB1dD1kZWZhdWx0ZGljdChpbnQpCiAgICBmb3IgZCBpbiBpbnB1dDoKICAgICAgICBmb3IgaXRlbSBpbiBkOgogICAgICAgICAgIG91dHB1dFtpdGVtWzBdXSs9aXRlbVsxXQogICAgcmV0dXJuIGRpY3Qob3V0cHV0KQoKZGVmIEJpZ1llbGxvd0NhY3R1cyhpbnB1dCk6CiAgICBpbnB1dCA9IHNvcnRlZChjaGFpbigqaW5wdXQpLCBrZXk9bGFtYmRhIHg6IHhbMF0pCiAgICBvdXRwdXQgPSB7fQogICAgZm9yIGssIGcgaW4gZ3JvdXBieShpbnB1dCwga2V5PWxhbWJkYSB4OiB4WzBdKToKICAgICAgICBvdXRwdXRba10gPSBzdW0oeFsxXSBmb3IgeCBpbiBnKQogICAgcmV0dXJuIG91dHB1dAoKZGVmIG1lcmdlX3dpdGgoZDEsIGQyLCBmbj1sYW1iZGEgeCwgeTogeCArIHkpOgogICAgcmVzID0gZDEuY29weSgpCiAgICBmb3Iga2V5LCB2YWwgaW4gZDIuaXRlcml0ZW1zKCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXNba2V5XSA9IGZuKHJlc1trZXldLCB2YWwpCiAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICByZXNba2V5XSA9IHZhbAogICAgcmV0dXJuIHJlcwoKZGVmIGFzdHluYXgoaW5wdXQpOgogICAgcmV0dXJuIHJlZHVjZShtZXJnZV93aXRoLCBtYXAoZGljdCxpbnB1dCkpCgpkaW0gPSA4MAppbnB1dCA9IFtbcm5kaXRlbSgpIGZvciBpIGluIHhyYW5nZShkaW0pXSBmb3IgaiBpbiB4cmFuZ2UoZGltKV0KCnJlc3VsdHMgPSBbKGsuZnVuY19uYW1lLCB0aW1laXQobGFtYmRhOiBrKGlucHV0KSwgbnVtYmVyPTMpKSBmb3IgayBpbiAoa29zLCBrb3MyLCBpbml0aWFsLCBCaWdZZWxsb3dDYWN0dXMsIGFzdHluYXgpXQpyZXN1bHRzLnNvcnQoa2V5PW9wZXJhdG9yLml0ZW1nZXR0ZXIoMSkpCnByaW50ICdcbicuam9pbihzdHIuZm9ybWF0KCd7OjIwfXt9JywgKngpIGZvciB4IGluIHJlc3VsdHMpCg==