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

newbie

Опубликован:  2018-09-04T13:55:36.341953Z
Отредактирован:  2018-09-04T13:46:51.273289Z

Предлагаю вашему вниманию одно из возможных решений стандартной для Python3 учебной задачи на преобразование данных из одного типа в другой. Вся отладка при решении производится в интерактивном режиме интерпретатора.

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

Встроенные функции int и str сделали бы эту задачу скучной и неинтересно, но, поскольку условия задачи запрещают их использование, поиск решения, использующего другие стандартные средства Питона, может оказаться неожиданно занимательным - прекрасная возможность продемонстрировать работу встроенных функций Питона, без которых жизнь скучна. Для решения задачи мне понадобится только терминальная программа и интерпретатор PythonЗ.

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

>>> 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)))
{'3': 3, '7': 7, '8': 8, '4': 4, '5': 5, '9': 9, '1': 1, '0': 0, '6': 6, '2': 2}

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

>>> [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. Питон - красавец.

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

F6ypVQjLr6.png

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