В поисках компактного FizzBuzz на Python

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.
source: http://www.mwctoys.com/REVIEW_010413a.htm
source: http://www.mwctoys.com/REVIEW_010413a.htm

Пришло время оживить преданный забвению FizzBuzz. Попробуем найти самое компактное решение FizzBuzz на Python.


Условие задачи

Напишите программу, печатающую числа от 1 до 100. Вместо чисел кратных трём, программа должна печатать 'Fizz'. Вместо чисел кратных пяти - 'Buzz'. Если число кратно и трём, и пяти, программа должна печатать 'FizzBuzz'.

Основа

Начнём со стандартного, классического решения:

for i in range(1, 101):
    if i%3==0 and i%5==0:
        print('FizzBuzz')
    elif i%3==0:
            print('Fizz')
    elif i%5==0:
            print('Buzz')
    else:
        print(i)

Укладываем стандартное решение в стандартный однострочник

print('\n'.join('FizzBuzz' if i%3==0 and i%5==0 else 'Fizz' if i%3==0 else 'Buzz' if i%5==0 else str(i) for i in range(1, 101)))

Избавляемся от Join, приручаем Print

[print('FizzBuzz' if i%3==0 and i%5==0 else 'Fizz' if i%3==0 else 'Buzz' if i%5==0 else i) for i in range(1, 101)]

Добавляем срез, укрощаем if else

[print('FizzBuzz'[4 if i%3 else 0:4 if i%5 else 8] or i) for i in range(1, 101)]

Оптимизируем срез, избавляемся от if else

[print('FizzBuzz'[i*i%3*4:8--i**4%5] or i) for i in range(1, 101)]

Сократили неплохо. Но, похоже с этой вариацией дальше не продвинуться. Пробуем иной вариант.

Заменяем срез конкатенацией, вертаем оператор modulo

[print('Fizz'*(i%3==0)+'Buzz'*(i%5==0) or i) for i in range(1, 101)]

Оптимизируем решение. Выравниваем по длине со срезом

[print((i%3<1)*'Fizz'+(i%5<1)*'Buzz' or i) for i in range(1, 101)]

Уходим в отрыв. Модифицируем окончательный вариант

[print(i%3//2*'Fizz'+i%5//4*'Buzz' or i+1) for i in range(100)]

А что по скорости?

print('\n'.join('FizzBuzz' if i%3==0 and i%5==0 else 'Fizz' if i%3==0 else 'Buzz' if i%5==0 else str(i) for i in range(1, 101))) # 2.53 msec
[print('FizzBuzz' if i%3==0 and i%5==0 else 'Fizz' if i%3==0 else 'Buzz' if i%5==0 else i) for i in range(1, 101)] # 8.11 msec
[print('FizzBuzz'[4 if i%3 else 0:4 if i%5 else 8] or i) for i in range(1, 101)] # 8.43 msec
[print('FizzBuzz'[i*i%3*4:8--i**4%5] or i) for i in range(1, 101)] # 8.31 msec
[print('Fizz'*(i%3==0)+'Buzz'*(i%5==0) or i) for i in range(1, 101)] # 8.38 msec
[print((i%3<1)*'Fizz'+(i%5<1)*'Buzz' or i) for i in range(1, 101)] # 8.4 msec
[print(i%3//2*'Fizz'+i%5//4*'Buzz' or i+1) for i in range(100)] # 8.49 msec

Методика расчёта: python -m timeit "выражение"


Вместо заключения

Помимо этой статьи, на Хабре мною опубликованы ещё пара статей на тему Python однострочников. Если интересно, ознакомиться можно по ссылкам ниже:

  • 5++ способов в одну строку на Python решить первую задачу Проекта Эйлера

  • Занимательные фигуры на Python в одну строку

Всем спасибо

Источник: https://habr.com/ru/post/593489/


Интересные статьи

Интересные статьи

Привет, Хабр! Мы продолжаем рассматривать конкретный практический вопрос — интеграцию Python для внедрения ML-моделей и расширенной аналитики в BI. В прошлом посте мы уже рассуждали о том, зачем это н...
Специально к старту нового потока курса Fullstack-разработчик на Python, представляем небольшой авторский обзор кроссплатформенного инструмента визуализации многопоточных...
В этой статье описываются операции по тестированию клиентской части приложения с помощью TestProject и pytest, а также способы выполнения тестов через GitHub Actions...
Сегодня публикуем вторую часть перевода материала, посвящённого статическому анализу больших объёмов серверного Python-кода в Instagram. → Первая часть
Один из самых острых вопросов при разработке на Битрикс - это миграции базы данных. Какие же способы облегчить эту задачу есть на данный момент?