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(dicts, fn=lambda x, y: x + y):
res = dict(dicts[0])
for dic in dicts[1:]:
for key, val in dic:
try:
res[key] = fn(res[key], val)
except KeyError:
res[key] = val
return res
astynax = merge_with
def astynax2(input):
res = defaultdict(int)
for k, v in chain(*input):
res[k] += v
return res
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, astynax2)]
results.sort(key=operator.itemgetter(1))
print '\n'.join(str.format('{:20}{}', *x) for x in results)
aW1wb3J0IHJhbmRvbSwgc3RyaW5nCmZyb20gY29sbGVjdGlvbnMgaW1wb3J0IENvdW50ZXIsIGRlZmF1bHRkaWN0CmltcG9ydCBvcGVyYXRvcgpmcm9tIGl0ZXJ0b29scyBpbXBvcnQgZ3JvdXBieSwgY2hhaW4KZnJvbSB0aW1laXQgaW1wb3J0IHRpbWVpdAoKCmRlZiBybmRzdHIobGVuKToKICAgIHJldHVybiAnJy5qb2luKHJhbmRvbS5jaG9pY2Uoc3RyaW5nLmxldHRlcnMpIGZvciBpIGluIHhyYW5nZShsZW4pKQoKZGVmIHJuZGl0ZW0oKToKICAgIHJldHVybiAocm5kc3RyKDIwKSwgcmFuZG9tLnJhbmRpbnQoMSwgMTAwMCkpCgphPVsoIjEzLjUiLDEwMCldCmI9WygiMTQuNSIsMTAwKSwgKCIxNS41IiwgMTAwKV0KYz1bKCIxNS41IiwxMDApLCAoIjE2LjUiLCAxMDApXQppbnB1dD1bYSxiLGNdCgoKZGVmIGtvcyhpbnB1dCk6CiAgICByZXR1cm4gcmVkdWNlKG9wZXJhdG9yLmFkZCwgKENvdW50ZXIoZGljdCh4KSkgZm9yIHggaW4gaW5wdXQpKQoKZGVmIGtvczIoaW5wdXQpOgogICAgZGVmIHUoYSxiKToKICAgICAgICBhLnVwZGF0ZShiKQogICAgICAgIHJldHVybiBhCiAgICByZXR1cm4gcmVkdWNlKHUsIChDb3VudGVyKGRpY3QoeCkpIGZvciB4IGluIGlucHV0KSkKCmRlZiBpbml0aWFsKGlucHV0KToKICAgIG91dHB1dD1kZWZhdWx0ZGljdChpbnQpCiAgICBmb3IgZCBpbiBpbnB1dDoKICAgICAgICBmb3IgaXRlbSBpbiBkOgogICAgICAgICAgIG91dHB1dFtpdGVtWzBdXSs9aXRlbVsxXQogICAgcmV0dXJuIGRpY3Qob3V0cHV0KQoKZGVmIEJpZ1llbGxvd0NhY3R1cyhpbnB1dCk6CiAgICBpbnB1dCA9IHNvcnRlZChjaGFpbigqaW5wdXQpLCBrZXk9bGFtYmRhIHg6IHhbMF0pCiAgICBvdXRwdXQgPSB7fQogICAgZm9yIGssIGcgaW4gZ3JvdXBieShpbnB1dCwga2V5PWxhbWJkYSB4OiB4WzBdKToKICAgICAgICBvdXRwdXRba10gPSBzdW0oeFsxXSBmb3IgeCBpbiBnKQogICAgcmV0dXJuIG91dHB1dAoKZGVmIG1lcmdlX3dpdGgoZGljdHMsIGZuPWxhbWJkYSB4LCB5OiB4ICsgeSk6CiAgICByZXMgPSBkaWN0KGRpY3RzWzBdKQogICAgZm9yIGRpYyBpbiBkaWN0c1sxOl06CiAgICAgICAgZm9yIGtleSwgdmFsIGluIGRpYzoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgcmVzW2tleV0gPSBmbihyZXNba2V5XSwgdmFsKQoJICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAJcmVzW2tleV0gPSB2YWwKICAgIHJldHVybiByZXMKCmFzdHluYXggPSBtZXJnZV93aXRoCgpkZWYgYXN0eW5heDIoaW5wdXQpOgogICAgcmVzID0gZGVmYXVsdGRpY3QoaW50KQogICAgZm9yIGssIHYgaW4gY2hhaW4oKmlucHV0KToKICAgICAgICByZXNba10gKz0gdgogICAgcmV0dXJuIHJlcwoKZGltID0gODAKaW5wdXQgPSBbW3JuZGl0ZW0oKSBmb3IgaSBpbiB4cmFuZ2UoZGltKV0gZm9yIGogaW4geHJhbmdlKGRpbSldCgpyZXN1bHRzID0gWyhrLmZ1bmNfbmFtZSwgdGltZWl0KGxhbWJkYTogayhpbnB1dCksIG51bWJlcj0zKSkgZm9yIGsgaW4gKAogICAga29zLCBrb3MyLCBpbml0aWFsLCBCaWdZZWxsb3dDYWN0dXMsIGFzdHluYXgsIGFzdHluYXgyKV0KcmVzdWx0cy5zb3J0KGtleT1vcGVyYXRvci5pdGVtZ2V0dGVyKDEpKQpwcmludCAnXG4nLmpvaW4oc3RyLmZvcm1hdCgnezoyMH17fScsICp4KSBmb3IgeCBpbiByZXN1bHRzKQo=