Python3, решаем простые задачи с помощью встроенных функций

avm

Опубликован:  2018-02-13T05:40:19.289818Z
1300

Условия задачи: все символы строки являются цифрами от 0 до 9, необходимо преобразовать эту строку в число, а затем полученное число преобразовать обратно в строку, допускается использовать любые встроенные функции, кроме int и str.

Конечно, встроенные функции int и str делают эту задачу скучной и неинтересной, видимо поэтому авторы задачи позаботились о качественном наполнении досуга начинающих программистов и запретили забивать гвозди молотком. :) Ладно, посмотрим, как можно решить эту задачу другими стандартными средствами Питона.

На этот раз, кроме демонстрации поиска возможного решения в интерактивной сессии интерпретатора Python3, у меня есть возможность продемонстрировать ещё и встроенные функции Питона, без которых жизнь скучна. Как обычно, мне понадобится терминальная программа и интерпретатор.

Начну я с заданной строки:

>>> s = '54709879023'

Чтобы преобразовать эту строку в число, у Питона есть цифры:

>>> from string import digits
>>> digits
'0123456789'

и числа:

>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Соединяю цифры с числами, ставлю в соответствие каждой цифре соответствующее целое число:

>>> dict(zip(digits, range(10)))
{'7': 7, '2': 2, '0': 0, '4': 4, '8': 8, '9': 9, '1': 1, '6': 6, '3': 3, '5': 5}

Имея такой словарь, достаточно просто получить список, каждый элемент которого будет целым числом и будет соответствовать каждой цифре в заданной строке:

>>> [dict(zip(digits, range(10)))[i] for i in s]
[5, 4, 7, 0, 9, 8, 7, 9, 0, 2, 3]

Умножу каждый элемент этого списка на 10 в соответствующей степени:

[item * pow(10, len(s) - step) for step, item in enumerate([dict(zip(digits, range(10)))[i] for i in s], 1)]
[50000000000, 4000000000, 700000000, 0, 9000000, 800000, 70000, 9000, 0, 20, 3]

Сумма чисел в полученном списке является искомым числом:

>>> n = sum(item * pow(10, len(s) - step) for step, item in enumerate([dict(zip(digits, range(10)))[i] for i in s], 1))
>>> n
54709879023

Таким образом, решение первой части задачи является типичным для Питона однострочником, в котором используется 7 различных встроенных функций: sum, pow, len, enumerate, dict, zip, range.

Проследуем далее, обратное преобразование. Чтобы преобразовать число в строку, мне необходимо посчитать его порядок, а именно меня интересует количество знаков после самого старшего разряда. В заданном числе их 10. Посчитаю я его так:

>>> order = 0
>>> while not 1 <= n // pow(10, order) <= 9:
...     order += 1
... 
>>> order
10

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

>>> [n - n // pow(10, i) * pow(10, i) for i in reversed(range(1, order + 2))]
[54709879023, 4709879023, 709879023, 9879023, 9879023, 879023, 79023, 9023, 23, 23, 3]

Заданное число имеет нули, поэтому на соответствующих местах в списке числа имеют на один разряд меньше.

Из этого списка достаточно просто получить поразрядный список:

>>> [item // pow(10, order - step) for step, item in enumerate([n - n // pow(10, i) * pow(10, i) for i in reversed(range(1, order + 2))])]
[5, 4, 7, 0, 9, 8, 7, 9, 0, 2, 3]

Ух... Теперь просто склеиваю полученные числа в строку, используя уже импортированные цифры:

>>> result = ''.join(digits[i] for i in [item // pow(10, order - step) for step, item in enumerate([n - n // pow(10, i) * pow(10, i) for i in reversed(range(1, order + 2))])])

Убеждаюсь, что результат соответствует заданной строке:

>>> result == s
True
>>> 

Таким образом, решение второй части задачи тоже является однострочником, а к списку использованных встроенных функций добавилась функция reversed. Питон - красавец.

Вся отладка выглядит так:

sakura

 
Метки:  python3x, newbie, builtins
Комментарии: