Почему sum() в python предполагает, что в коллекции находятся именно числа?
Функция sum() в python3 имеет сигнатуру sum(iterable, start=0). Какая причина того, что start изначально инициализируется нулем?
Почему бы не инициализировать start внутри самой функции первым объектом коллекции, если он присутствует, а иначе возвращать None?
Зачем это может быть полезно? Для начала, просто чтобы работа функции соответствовала ожиданиям: если у меня реализован для объекта метод __add, то я хочу его складывать, и я ожидаю, что функция суммы мне сложит все мои объекты в один, а не вылетит с ошибкой TypeError.
Ответы (1 шт):
Правильный тип возвращаемого значения, как уже упоминалось в комментарии Xander - это, на мой взгляд, основная причина такого поведения sum. Возьмём простой пример:
def my_super_sum(arr1, arr2):
return sum(arr) * 2 - sum(arr2)
В случае, если sum точно знает, что работает с числами, проблем тут не возникнет при любой наполненности коллекций arr1 и arr2. Какие бы наборы чисел (в виде итератора) ни подать этой функции на вход, включая пустые коллекции (да, такое бывает, и это совершенно нормально) - всё будет работать, если функция sum от пустой коллекции возвращает 0. Но не в случае, если она вернёт None. Ну либо тогда придётся менять и поведение питона при сложении чисел с None, считая его нулём. Короче, всё текущее поведение питона "поплывёт".
Проблема с вашим вариантом в том, что Python - язык без строгой типизации, поэтому пустой, например, список не имеет никакого типа. Нет элементов - нет типа. Нет типа - непонятно, что мы суммируем и как.
А ещё могут быть коллекции из смешанных типов. В питоновском списке могут быть произвольные элементы, любых типов, вперемешку. Поэтому ориентироваться именно на первый элемент в данном случае как-то очень не по питоновски.
Как правильно заметил mrEvgenX, если хотите ориентироваться на первый элемент последовательности - делайте это в явном виде, используя функцию reduce, которая именно под этот вариант и заточена.