Решаем с 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
. Питон - красавец.
Вся отладка выглядит так:
Первая часть задачи, а именно преобразование строки с цифрами в целое число, решается ещё проще, без лишних импортов и словарей.
>>> s = '54709879023' >>> n = sum((ord(s[i]) - 48) * pow(10, len(s) - i - 1) for i in range(len(s))) >>> n 54709879023 >>>
Вторую часть задачи тоже можно существенно упростить... Как, расскажу чуть позже.
Вторая часть задачи решается в один цикл.
>>> def conv(num): ... box = [] ... while num: ... f = num * 0.1 ... num = int(f) ... box.insert(0, chr(round((f - num)* 10) + 48)) ... return ''.join(box) ... >>> n = 54709879023 >>> s = conv(n) >>> s '54709879023' >>>