![](https://habrastorage.org/webt/cq/lu/p0/cqlup0xhwuo0wxacu0hafca6piu.png)
На картинке вы видите обычную таблицу умножения, которая, думаю, всем хорошо знакома.
Ничего особенного в ней нет, кроме того, что весь алгоритм ее построения сжат до одной стандартной Python’овской строки в 79 символов (см. PEP8). Кому интересно добро пожаловать под кат.
Для начала, стоит ответить на появившийся у многих вопрос «А зачем это?». Все сложилось из двух факторов, во-первых я, по настоятельной рекомендации одного хорошего человека, занялся углубленным изучением Python’а, а во-вторых мне нравится концепция демосцены. Результатом стало желание написать (конечно слишком громко сказано) что-нибудь очень маленькое (в идеале в одну строку), но наглядное, используя для всего этого особенности кодинга на Python’е. Я решил вывести на экран таблицу умножения.
Стоит отметить, что пишу я на Python3.7. Версии младше 3.6 не подойдут из-за отсутствия поддержки f-строк, и в итоге рабочий скрипт превысит длину в 79 символов.
Как восемь строк превратились в одну
Для начала я написал код выводящий таблицу умножения, абсолютно не заботясь о компактности:
![](https://habrastorage.org/webt/qa/bx/fb/qabxfb_6gxyhv4acsvv-kjcrkly.png)
Листинг
def MultiTabl():
tabl = ''
for y in range(1,11):
for x in range(1,11):
tabl += f'{x*y}\t'
tabl += f'\n'
return tabl
Сформировать значения таблицы можно, используя генераторы, а циклы оставить для распаковки списков. Минусом такого подхода оказалось большее количество строк:
![](https://habrastorage.org/webt/ql/vg/nj/qlvgnjr0ycb1tittfpudigeawxe.png)
Листинг
def MultiTabl():
nums = [[x*y for x in range(1,11)] for y in range(1,11)]
tabl = ''
for line in nums:
for item in line:
tabl += f'{item}\t'
tabl += f'\n'
return tabl
Генератору можно отдать и расстановку Tab’ов (‘\t’) используя f-строки:
nums = [[f'{x*y}\t' for x in range(1,11)] for y in range(1,11)]
Если извлеченный в первом цикле список склеить в строку, с помощью строкового метода join(), использовать параллельное назначение переменных и разместить цикл в одной строке, то размеры кода значительно уменьшатся:
![](https://habrastorage.org/webt/rs/te/a4/rstea4fukmcdepksytenjtsp1og.png)
Листинг
def MultiTabl():
nums, tabl = [[f'{x*y}\t' for x in range(1,11)] for y in range(1,11)], ''
for line in nums: tabl += ''.join(line) + '\n'
return tabl
А если внести join() и ‘\n’ в генератор:
def MultiTabl():
nums, tabl = [''.join([f'{x*y}\t' for x in range(1,11)])+'\n' for y in range(1,11)], ''
for line in nums: tabl += line
return tabl
Теперь в нашем распоряжении список из строк, и его тоже можно склеить с помощью join(), избавившись тем самым от циклов:
def MultiTabl():
tabl = ''.join([''.join([f'{x*y}\t' for x in range(1,11)])+'\n' for y in range(1,11)])
return tabl
Ну и обещанный вариант в одну строку (от print, конечно, не избавиться)
print(
''.join([''.join([f'{x*y}\t' for x in range(1,11)])+'\n' for y in range(1,11)])
)
Конечно, гуру Python’а скажут “И что тут такого?”, но стоит заметить, что указанный подход не является очевидным для начинающих.
Не стоит воспринимать сей опус слишком серьезно, я его писал как разминку перед большой статьей, будет замечательно если он вызовет улыбку, и просто великолепно если принесет пользу.