Skip to content

Instantly share code, notes, and snippets.

@khorpy
Created July 27, 2018 16:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save khorpy/f6341484b7bffc6003f4d36b074e6ee4 to your computer and use it in GitHub Desktop.
Save khorpy/f6341484b7bffc6003f4d36b074e6ee4 to your computer and use it in GitHub Desktop.
Задача о сравнении подходов
import random
from collections import defaultdict
from functools import reduce
from timeit import timeit
from itertools import groupby
from operator import itemgetter
from statistics import mean
AMAX = 65
l = [{'age': random.randint(18, AMAX), 'rate': random.randint(1, 1000)}
for x in range(100000)]
# ========================
def max_for(l):
totals = [0 for i in range(AMAX + 1)]
counters = [0 for i in range(AMAX + 1)]
for p in l:
totals[p['age']] += p['rate']
counters[p['age']] += 1
averages = []
for i, v in enumerate(counters):
if counters[i] > 0:
averages.append(totals[i] / counters[i])
return max(averages)
# ========================
# ========================
def max_map(l):
def fn(a, b):
a[b['age']].append(b['rate'])
return a
return max(
map(
lambda x: sum(x) / len(x),
reduce(fn, [defaultdict(list)] + l).values()
)
)
# ========================
def max_fun(l):
return max([mean(i['rate'] for i in g)
for k, g in groupby(l, key=itemgetter('age'))])
t1 = timeit('max_for(l)', 'from __main__ import max_for, l', number=1)
t2 = timeit('max_map(l)', 'from __main__ import max_map, l', number=1)
t3 = timeit('max_fun(l)', 'from __main__ import max_fun, l', number=1)
print(t1)
print(t2)
print(t3)
@axrn
Copy link

axrn commented Dec 9, 2021

The results between max_fun(l) and max_for(l) | max_map(l) are not equal if we take l from code above. But everything is ok when test list is small. So, there is some logical bug in max_fun (or vice versa in max_for | max_map?).

l = [{'age': random.randint(18, 65), 'rate': random.randint(1, 1000)} for x in range(100000)]
print(max_for(l)) #>> 512.7681692732291
print(max_map(l)) #>> 512.7681692732291
print(max_fun(l)) #>> 1000

test = [{'age': 18, 'rate': 30}, {'age': 18, 'rate': 15}, {'age': 50, 'rate': 35}]
print(max_for(test)) #>> 35.0
print(max_map(test)) #>> 35.0
print(max_fun(test)) #>> 35

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment