Как выжать максимум из однострочника 🧠

Что там с подсчетом ноликов?

Базовый инстинкт большинства — написать list comprehension:
max([len(i) for i in s.split('1')])

Работать будет. Но вы сначала сплитите строку (создавая список в памяти), а потом прогоняете по нему цикл, чтобы создать ещё один список целых чисел, чтобы скормить его max(). Двойной расход памяти на ровном месте.

Но можно и генератор:
max((len(chunk) for chunk in s.split('1')))

По памяти тут всё красиво — промежуточный список длин не создается. Но вот по скорости генераторные выражения внутри встроенных функций в Python работают медленнее из-за оверхеда на итерацию и вызовы функций на уровне байткода.

А так еще лучше:
max(map(len, s.split('1')))

Мы избавляемся от питонячьего цикла. map реализован на Си, он ленивый, работает быстро, память не жрет. Большинство на этом радостно успокаивается.

Но... и это не оч. Задайте себе вопрос: зачем мы вообще считаем длины всех кусков до того, как найдем максимальный?

Строки в Python сравниваются лексикографически. Символ по символу. Следовательно, строка "000" всегда больше, чем "00". Нам вообще не нужно вычислять длины подстрок для сравнения.

Надо так!
len(max(s.split('1')))


Почему это лучшее решение? 🤔
1. Вызов s.split('1') мгновенно отдает список строк.
2. max() проглатывает этот список и на уровне C сравнивает сами строки. Никаких map, никаких вызовов len для каждого элемента, никакого вызова функций в цикле.
3. Мы берем len() ровно один раз — от победившей строки.

Меньше телодвижений интерпретатора = быстрее код.

#алгособес