Как сделать перебор списка цифр (названий) и остановиться, если цифра совпадает с числом?
Есть список названий цифр:
nums = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
Если n = 20 и я сделаю:
n = 20
n_list = []
for i in str(n):
n_list.append(nums[int(i)])
То получу:
twozero
Далее, я получу seven, сделав:
nums[len("".join(n_list))]
В seven 5 букв, соответственно, дальше я получу five. В five 4 буквы, значит дальше я получу four. В four 4 буквы, значит я снова получу 4. На этом цикл заканчивается.
Я не понимаю как сделать так, чтобы это считалось в цикле
То есть конечный результат должен получиться такой:
['twozero', 'seven', 'five', 'four']
Ответы (2 шт):
nums = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
n, out, digit = 20, [], None
x = ''.join(nums[int(i)] for i in str(n)) # стартовое значение X
while x != digit: # цикл, пока x не равен digit
out.append(x) # добавляем очередной x в итоговый список
digit, x = x, nums[len(x)] # х сохраняем в digit, а новый х извлекаем из списка nums
print(out)
['twozero', 'seven', 'five', 'four']
В случае, если длина x будет превышать наибольший индекс списка nums (например, если задать n=100, то x будет onezerozero, а len(x)==11), возникнет ошибка IndexError: list index out of range. Здесь возможны как минимум варианты - а) добавить в список значений 'ten', 'eleven', 'twelve', ... или б) остановить вычисления, сообщив о такой ситуации.
Что интересно, все вычисления на протестированном диапазоне 0-100 (включительно) завершаются либо на four (~90%) либо ошибкой (~10%). Это и закономерно, поскольку среди рассмотренных цифр только у four кол-во символов равно самому числу:
def fun(n):
nums = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
out, digit = [], None
x = ''.join(nums[int(i)] for i in str(n)) # стартовое значение X
while x != digit: # цикл, пока x не равен digit
out.append(x) # добавляем очередной x в итоговый список
pos = len(x)
if pos > len(nums) - 1:
return out + ['IndexError']
digit, x = x, nums[pos] # х сохраняем в digit, а новый х извлекаем из списка nums
return out
stat = {}
for n in range(101):
res = fun(n)
if res[-1] in stat:
stat[res[-1]] += 1
else:
stat[res[-1]] = 1
print(res)
print(stat)
...
['ninefour', 'eight', 'five', 'four']
['ninefive', 'eight', 'five', 'four']
['ninesix', 'seven', 'five', 'four']
['nineseven', 'nine', 'four']
['nineeight', 'nine', 'four']
['ninenine', 'eight', 'five', 'four']
['onezerozero', 'IndexError']
{'four': 91, 'IndexError': 10}
Выражение step = ''.join(nums[int(d)] for d in str(n)) превращает число n в строку из числительных. "Обратное" преобразование из строки в число: n = len(step). Повторяется всё в цикле, который прерывается по условию сохранения длины len(step) == n:
nums = [
'zero', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine'
]
def steps(n):
steps = []
while True:
step = ''.join(nums[int(d)] for d in str(n))
steps.append(step)
if len(step) == n:
return steps
n = len(step)
print(steps(int(input())))
$ echo 20 | py temp.py ['twozero', 'seven', 'five', 'four'] $ echo 33 | py temp.py ['threethree', 'onezero', 'seven', 'five', 'four']