Pull to refresh

Таблица умножения в одну строку

Reading time2 min
Views18K

На картинке вы видите обычную таблицу умножения, которая, думаю, всем хорошо знакома.
Ничего особенного в ней нет, кроме того, что весь алгоритм ее построения сжат до одной стандартной Python’овской строки в 79 символов (см. PEP8). Кому интересно добро пожаловать под кат.

Для начала, стоит ответить на появившийся у многих вопрос «А зачем это?». Все сложилось из двух факторов, во-первых я, по настоятельной рекомендации одного хорошего человека, занялся углубленным изучением Python’а, а во-вторых мне нравится концепция демосцены. Результатом стало желание написать (конечно слишком громко сказано) что-нибудь очень маленькое (в идеале в одну строку), но наглядное, используя для всего этого особенности кодинга на Python’е. Я решил вывести на экран таблицу умножения.

Стоит отметить, что пишу я на Python3.7. Версии младше 3.6 не подойдут из-за отсутствия поддержки f-строк, и в итоге рабочий скрипт превысит длину в 79 символов.

Как восемь строк превратились в одну


Для начала я написал код выводящий таблицу умножения, абсолютно не заботясь о компактности:



Листинг
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


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



Листинг
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(), использовать параллельное назначение переменных и разместить цикл в одной строке, то размеры кода значительно уменьшатся:



Листинг
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’а скажут “И что тут такого?”, но стоит заметить, что указанный подход не является очевидным для начинающих.

Не стоит воспринимать сей опус слишком серьезно, я его писал как разминку перед большой статьей, будет замечательно если он вызовет улыбку, и просто великолепно если принесет пользу.
Tags:
Hubs:
If this publication inspired you and you want to support the author, do not hesitate to click on the button
0
Comments53

Articles