Мне нужно преобразовать строку в целое слово в диапазоне от [от нуля до десяти]

Пример ввода 1:

a=two3four

Необходимый результат:

 234

Пример 2:

b=fivesixseven

Необходимый результат:

567

Мой код:

def w2n (number):
  words = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]
  return "".join(str(words.index(number[i])) for i in range(0,len(number)))

print(w2n("onetwoseven"))  

Я получаю ошибку в этом коде

Traceback (most recent call last):
  File "HelloWorld.py", line 5, in <module>
    print(w2n("onetwoseven"))    
  File "HelloWorld.py", line 3, in w2n
    return "".join(str(words.index(number[i])) for i in range(0,len(number)))
  File "HelloWorld.py", line 3, in <genexpr>
    return "".join(str(words.index(number[i])) for i in range(0,len(number)))
ValueError: 'o' is not in list

Пожалуйста, объясните мне, почему возникает эта ошибка и как получить вывод для моих двух примеров ввода (дан).

0
Heisenberg 4 Фев 2022 в 11:04
number[i] — одна буква.
 – 
DYZ
4 Фев 2022 в 11:06
Верно, ваш words.index – это единственный символ с индексом i, поэтому в приведенном вами примере сообщения об ошибке вы видите 'o' in not in list, это первая буква "one" в "onetwoseven".
 – 
PangolinPaws
4 Фев 2022 в 11:08
Я неправильно возвращаю свой код. Я не знаю, как разбить onetwothree на ["one", "two", "three"]
 – 
Heisenberg
4 Фев 2022 в 11:19

3 ответа

Это решение, которое я придумал:

def w2n(number):
    words = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]
    for i in words:
        number = number.replace(i, str(words.index(i)))
    return int(number)


a="two3four"
print(w2n(a)) # 234
b="fivesixseven"
print(w2n(b)) # 567
3
Achxy_ 4 Фев 2022 в 11:38

Вы можете использовать регулярные выражения для извлечения цифр и их имен, затем заменить извлеченные имена их цифровыми представлениями и объединить их в строку. Имейте в виду, что «десять» — это не цифра, и ее не должно быть в списке.

import re

# A dictionary of names of digits
digits = {'zero': '0', 'one': '1', 'two': '2', 'three': '3', 'four': '4', 
          'five': '5', 'six': '6', 'seven': '7', 'eight': '8', 'nine': '9'}
digits.update({str(i): str(i) for i in range(10)})

# The regular expression for searching the names
numbers = re.compile("|".join(digits))

"".join(digits[w] for w in numbers.findall("two3four"))
#'234'
"".join(digits[w] for w in numbers.findall("fivesixseven"))
#'567'
1
DYZ 4 Фев 2022 в 11:17
Привет @DYZ У меня есть одно сомнение в этом коде, зачем использовать "|" в перекомпиляции?
 – 
Heisenberg
4 Фев 2022 в 11:20
"|" в регулярном выражении означает "или".
 – 
DYZ
4 Фев 2022 в 11:21
Большое вам спасибо, сэр
 – 
Heisenberg
4 Фев 2022 в 11:24

Ответ на регулярное выражение очень умный, но если вам нужно решение без регулярного выражения, вы можете использовать длину чисел как слов, чтобы получить их начальный и конечный индекс в исходном вводе:

def w2n(number):
    words = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]

    for word in words:
        if word in number:
            start = number.index(word)
            end = start + len(word)
            print(f'Word "{word}" starts at {start} and ends at {end}')
            extracted_word = number[start:end]
            number = number.replace(word, str(words.index(extracted_word)) )

    return number

print( w2n('two3four') )

print( w2n('fivesixseven') )

Переписывая исходный ввод числовым представлением каждого слова, мы игнорируем любые цифры во вводе и оставляем их на месте, как вы можете видеть в примере "two3four".

Это выведет:

Word "two" starts at 0 and ends at 3
Word "four" starts at 2 and ends at 6
234

Word "five" starts at 0 and ends at 4
Word "six" starts at 1 and ends at 4
Word "seven" starts at 2 and ends at 7
567
0
PangolinPaws 4 Фев 2022 в 11:21
1
Большое спасибо, сэр, теперь я понял
 – 
Heisenberg
4 Фев 2022 в 11:24