Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Используйте циклы вместо reduce.
Кроме того он несколько проигрывает по производительности
from time import time
from functools import reduce
from operator import add
lst = range(1,10000000)
r1, r2 = 0, 0
t1 = time()
r1 = reduce(add, lst)
t1 = time() - t1
t2 = time()
for i in lst:
r2 = add(i, r2)
t2 = time() - t2
print(t1)
print(t2)operator. Если нужно создавать свою лямбду, то вариант с циклом быстрее.from time import time
from functools import reduce
lst = xrange(1,10000000)
r1, r2 = 0, 0
t1 = time()
r1 = reduce(lambda x, y: x + y, lst)
t1 = time() - t1
t2 = time()
for i in lst:
r2 = i + r2
t2 = time() - t2
print(t1)
print(t2)reduce замечательная вещь, но только в ФП языках. А Python, как ни крути, таковым не является.Но в целом я согласен, код с reduce тяжелее читается
for p in pupils:
print p.name, p.height
highest_pupil = None
max_height = 0
for p in pupils:
if p.height > max_height:
highest_pupil = p
max_height = p.height
return highest_pupil
reduce(lambda p1, p2: p1 if p1.height > p2.height else p2, pupils)
def higher_pupil(p1, p2):
if p1.height > p2:
return p1
else:
return p2
reduce(higher_pupil, pupils)
reduce(lambda s, inv: s + inv.investment, investors)
reduce(lambda result, s: result + s, strings)
reduce(add_or_inc, words, {})
d = defaultdict(int)
for w in words:
d[w] += 1
Имея список инвесторов, найти общую сумму полученных инвестиций
sum([inv.investment for inv in investors])
Объединить (т.е., опять же, аккумулировать) строки (или списки)
''.join(strings)
В 3Б классе 25 учеников, нужно найти самого высокого из них.
pupils.sort(key=lambda pupil: pupil.height)
pupils[0]
max_height = max([pupil.height for pupil in pupils])
highest_pupil = [for pupil in pupils if pupil.height==max_height][0]
highest_pupil = pupils[0]
for pupil in pupils:
if pupil.height > highest_pupil.height:
highest_pupil = pupil
return highest_pupil
foreach относительно for — отсутствие необходимости в изменяемой «вручную» индексной переменной: меньше «менеджимых» програмимстом операторов — меньше потенциальных мест для ошибки.Что касается самого высокого ученика, то ваше решение некорректно: если список учеников пуст, то `highest_pupil =pupils[0]` выдаст ошибку.Тогда корректность самой задачи сомнительна. SQL, насколько я помню,
max() в этом случае выдаст null — когда впервые увидел, был удивлён. Корректность применения фрагмента max_height = 0
перед циклом в этом случае тоже дискуссионна.Для меня лично, основное преимущество foreach относительно for — отсутствие необходимости в изменяемой «вручную» индексной переменной: меньше «менеджимых» програмимстом операторов — меньше потенциальных мест для ошибки.
One of Guido's key insights is that code is read much more often than it is written. The guidelines provided here are intended to improve the readability of code and make it consistent across the wide spectrum of Python code.
Тогда корректность самой задачи сомнительна. SQL, насколько я помню, max() в этом случае выдаст null — когда впервые увидел, был удивлён.
Вы сомневаетесь, следует ли обрабатывать списки нулевой длины?Уже до и за меня решено, что придётся это как-то делать. Сомнительна не задача, а корректность её постановки: что делать в случае пустого списка, не ясно.
А что вы тогда предлагаете делать с такими списками, на примере того же SQL — что, по вашему мнению, должна возвращать функция max, если селект вернул пустой result set?Тогда я ожидал ноль. Но потом понял, что
null — корректнее: положительность, в общем случае, никем не гарантирована. Ну тут пути три — 1) вернуть ноль (имеет смысл, если тип данных явно задан как положительный) 2) вернуть null или другое спец.значение 3) кинуть исключение. Выбор за разработчиком исходя из уточнённого смысла задачи.from functools import reduce
from timeit import timeit
import operator
def t0():
return sum(lst)
def t1():
return reduce(operator.add, lst)
def t2():
a = 0
for b in lst:
a += b
return b
def t3():
return reduce(lambda x, y: x + y, lst)
timeit(t0, number=100)
# 0.7890550769952824
timeit(t1, number=100)
# 3.882541635997768
timeit(t2, number=100)
# 3.9364478749994305
timeit(t3, number=100)
# 7.679830512999615
LISP, в Python есть синтаксис;-) (в смысле, кроме деревьев), в том числе и специальные идиомы языка, являющиеся аналогами этих функций.
result = []
for x in range(10):
for y in range(5):
if x * y > 10:
result.append((x, y))
result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]
Советы Google по кодированию на языке Python. Часть первая: советы по программированию