yyyuuu
Второй вайл ведь собирает значения из списка и возводит их в степень
Там надо использовать операцию += с результатом.
Краткий вариант на строке
>>> def isarm(s):
... return int(s) == sum(i ** len(s) for i in map(int, s))
...
>>> isarm('153')
True
>>> isarm('154')
False
>>>
Но на строках работать с числами не принято, так как работа со строками происходит гораздо медленнее, чем с числами. Когда функция вызывается десятки тысяч раз, это имеет значение. Да и сами строки могут содержать неожиданные символы, которые никак к числам не относятся, поэтому являются источником ошибок и требуют предварительной проверки строки на правильное число в ней.
Поэтому такие функции делают на числах
>>> def isarm(num):
... if num == 0:
... return True
... lst = []
... length = 0
... result = 0
... tmp = num
... while tmp > 0:
... lst.append(tmp % 10)
... length += 1
... tmp //= 10
... for i in lst:
... result += i ** length
... return num == result
...
>>> isarm(153)
True
>>> isarm(154)
False
>>>
Если по времени посмотреть, то числовая версия, хоть она и больше по размерам, но выполняется быстрее в два раза.
ipython3
In [1]: %paste
def isarm(num):
if num == 0:
return True
lst = []
length = 0
result = 0
tmp = num
while tmp > 0:
lst.append(tmp % 10)
length += 1
tmp //= 10
for i in lst:
result += i ** length
return num == result
## -- End pasted text --
In [2]: %timeit isarm(153)
100000 loops, best of 3: 3.51 us per loop
In [3]: %timeit isarm(154)
100000 loops, best of 3: 3.49 us per loop
In [4]:
In [1]: %paste
def isarm(s):
return int(s) == sum(i ** len(s) for i in map(int, s))
## -- End pasted text --
In [2]: %timeit isarm('153')
100000 loops, best of 3: 6.07 us per loop
In [3]: %timeit isarm('154')
100000 loops, best of 3: 6.11 us per loop
In [4]: