История изменений
Исправление Nervous, (текущая версия) :
Я думал, мой вариант жестоко всосет по производительности (перебор комбинаций), но нет:
import timeit
iterations = 10000
xs = [(0, 10.8), (1, 8.2), (2, 0.3)]
ys = [(0, 0.4), (3, 20.2), (2, 0.3)]
def one_imperative(a, b):
c = a + b
keys = set(map(lambda x: x[0], c))
result = []
for key in keys:
summ = 0
for x in c:
if x[0] == key:
summ += x[1]
result.append((key, summ))
return sorted(result, key=lambda x: x[1], reverse=True)
def one_pythonic(a, b):
c = a + b
keys = set(map(lambda x: x[0], c))
result = [(key, sum([x[1] for x in c if x[0] == key])) for key in keys]
return sorted(result, key=lambda x: x[1], reverse=True)
def two(xs, ys):
sum_dict = {x[0]: x[1] + y[1] for x in xs for y in ys if x[0] == y[0]}
result_dict = {**dict(xs), **dict(ys), **sum_dict}
result = [(k, v) for k,v in result_dict.items()]
return sorted(result, key=lambda x: x[1], reverse=True)
time_one_imperative = timeit.timeit("one_imperative(xs, ys)", "from __main__ import xs, ys, one_imperative", number=iterations)
time_one_pythonic = timeit.timeit("one_pythonic(xs, ys)", "from __main__ import xs, ys, one_pythonic", number=iterations)
time_two = timeit.timeit("two(xs, ys)", "from __main__ import xs, ys, two", number=iterations)
print("One imperative: ", time_one_imperative)
print("One pythonic: ", time_one_pythonic)
print("Two: ", time_two)
One imperative: 0.18978183099534363
One pythonic: 0.25368363698362373
Two: 0.1737681599915959
Может, начнет сосать на более длинных входных данных, надо проверить.
Исходная версия Nervous, :
Я думал, мой вариант жестоко всосет по производительности (перебор комбинаций), но нет:
import timeit
iterations = 10000
xs = [(0, 10.8), (1, 8.2), (2, 0.3)]
ys = [(0, 0.4), (3, 20.2), (2, 0.3)]
def one_imperative(a, b):
c = a + b
keys = set(map(lambda x: x[0], c))
result = []
for key in keys:
summ = 0
for x in c:
if x[0] == key:
summ += x[1]
result.append((key, summ))
return sorted(result, key=lambda x: x[1], reverse=True)
def one_pythonic(a, b):
c = a + b
keys = set(map(lambda x: x[0], c))
result = [(key, sum([x[1] for x in c if x[0] == key])) for key in keys]
return sorted(result, key=lambda x: x[1], reverse=True)
def two(xs, ys):
sum_dict = {x[0]: x[1] + y[1] for x in xs for y in ys if x[0] == y[0]}
result_dict = {**dict(xs), **dict(ys), **sum_dict}
result = [(k, v) for k,v in result_dict.items()]
return sorted(result, key=lambda x: x[1], reverse=True)
time_one_imperative = timeit.timeit("one_imperative(xs, ys)", "from __main__ import xs, ys, one_imperative", number=iterations)
time_one_pythonic = timeit.timeit("one_pythonic(xs, ys)", "from __main__ import xs, ys, one_pythonic", number=iterations)
time_two = timeit.timeit("two(xs, ys)", "from __main__ import xs, ys, two", number=iterations)
print("One imperative: ", time_one_imperative)
print("One pythonic: ", time_one_pythonic)
print("Two: ", time_two)
One imperative: 0.18978183099534363
One pythonic: 0.25368363698362373
Two: 0.1737681599915959
Может, начнет сосать на более длинных входных данных, надо проверить.