Как .replace() только часть слова? И извлечение целого числа из строки?

avatar
Twissted
8 апреля 2018 в 00:11
55
1
1

Попытка выяснить, как заменить только часть слова, используя списки, циклы For и .replace(). Я также нахожусь в процессе выяснения того, как извлечь целое число из кода, чтобы +1 и вернуть число.

Пока мой код выглядит следующим образом:

dictZero = [ "zero", "none", "nil", "null" ]
dictOne = [ "one", "won", "juan" ]
dictTwo = [ "two", "to", "too", "tu" ]
dictThree = [ "three" ]
dictFour = [ "four", "for", "fore" ]

userInput = input ( "Enter your sentence to inflate: " )

for i in userInput.split():
    for e in dictFour:
        if e in i:
            userInput = userInput.replace ( i, "five" )
    for d in dictThree:
        if d in i:
            userInput = userInput.replace ( i, "four" )
    for c in dictTwo:
        if c in i:
            userInput = userInput.replace ( i, "three" )
    for b in dictOne:
        if c in i:
            userInput = userInput.replace ( i, "two" )
    for a in dictZero:
        if a in i:
            userInput = userInput.replace ( i, "one" )
    #This seems to work but not sure how to assign it back into the Input
    if int(i):
        i = int(i) + 1
        print (i)
print ( userInput)

Пример: Ввод = "Прежде чем я лягу спать в 16:30" Вывод = "Прежде чем я пойду на три кровати в 16:31"

По большей части код работает так, как я хочу. Если вы введете слово в список, оно заменит его соответствующим словом.

НО! Я не могу на всю жизнь понять, как разбить userInput на один шаг дальше, чтобы заменить слово, такое как «до», и получить результат как «пятый», а не пятый. Может быть, еще один оператор if с .split(), затем .join()?

Любая помощь или предложения будут оценены. Спасибо за ваше время.

Источник
DYZ
8 апреля 2018 в 00:32
0

int(i) вызывает исключение, если i является не целым числом.

Twissted
8 апреля 2018 в 00:39
0

Что это так, я просто бездельничал, чтобы посмотреть, смогу ли я найти способ вытащить число, которое будет увеличено на +1. Явно не лучший вариант. Это работает, если ввод является просто числом.

Ответы (1)

avatar
Aran-Fey
8 апреля 2018 в 00:44
1

Причина, по которой ваш код превращает "before" в "пять" вместо "befive", заключается в следующей строке кода:

userInput = userInput.replace ( i, "five" )

В этом контексте i — это строка «до», поэтому вы заменяете все слово на «пять». Правильная переменная для использования вместо i будет e, которая в настоящее время является строкой "для".

userInput = userInput.replace ( e, "five" )

Теперь мы получаем вывод: "Бефифи, я иду на три кровати в 16:30". Обратите внимание на двойную букву «е» в «Befivee». Это связано с тем, что вы неправильно расположили слова в dictFour:

.
dictFour = [ "four", "for", "fore" ]

Поскольку более короткое слово "for" указано перед более длинным словом "fore", код всегда будет заменять "for" при каждом появлении "fore", таким образом давая нам дубликат "e" в выводе. Вы должны переупорядочить списки таким образом, чтобы более длинные слова располагались перед более короткими:

.
dictFour = [ "four", "fore", "for" ]  # swap "for" and "fore"
dictTwo = [ "two", "too", "to", "tu" ]  # swap "to" and "too"

Следующая проблема связана с обработкой чисел во входных данных:

if int(i):
    i = int(i) + 1
    print (i)

int(i) выдаст ошибку ValueError, если слово не может быть преобразовано в число, что приводит к сбою программы. Даже если проверка пройдена, i = int(i) + 1 только обновляет значение переменной i, но не меняет число во входной строке.


Первое, что мы делаем, чтобы исправить код, — это избавляемся от нумерованных списков dictZero, dictOne и т. д. вместо этого сохраните их в списке или в словаре. В этом случае, поскольку очень важно правильно расположить значения, мы воспользуемся списком и отсортируем числа по убыванию:

.
replacements = [('five', [ "four", "fore", "for" ]),
                ('four', [ "three" ]),
                ('three', [ "two", "too", "to", "tu" ]),
                ('two', [ "one", "won", "juan" ]),
                ('one', [ "zero", "none", "nil", "null" ]),
                ]

Убывающий порядок важен, чтобы последующие замены не превращали "один" в "два", в "три" в "четыре" и т. д.

После этого мы можем приступить к исправлению кода. Вероятно, самый простой способ сделать это — разбить пользовательский ввод на список и выполнить замены в этом списке:

words = userInput.split()
for i, word in enumerate(words):
    # if the word is a number, increment it
    try:
        word = str(int(word) + 1)
    except ValueError:
        # if it isn't a number, loop over all replacements and substitute them
        for replacement, words_to_replace in replacements:
            for word_to_replace in words_to_replace:
                word = word.replace(word_to_replace, replacement)

    # assign the updated word back into the list
    words[i] = word

userInput = ' '.join(words)
print(userInput)  # output: Befive I go five bed at 1631

Еще один вариант — заменить все слова во входной строке напрямую и использовать регулярное выражение для увеличения чисел:

import re

for replacement, words_to_replace in replacements:
    for word_to_replace in words_to_replace:
        userInput = userInput.replace(word_to_replace, replacement)

userInput = re.sub(r'\d+', lambda match: str(int(match.group())+1), userInput)
print(userInput)  # output: Befive I go five bed at 1631
Twissted
8 апреля 2018 в 00:48
0

Я попробую этот материал и посмотрю, где я закончу. Я ценю ваше время и усилия!

Twissted
8 апреля 2018 в 00:59
0

Я понимаю, что ваш код работает безупречно, за исключением того, что мне пришлось изменить порядок списка, чтобы он начинался с самого большого числа вниз. Но, к сожалению, я мало в этом понимаю. Попробуйте и за исключением ValueError вне моей лиги. Очень хорошо сделано, и я постараюсь использовать все, что смогу, из вашего ответа. Еще раз спасибо

Aran-Fey
8 апреля 2018 в 01:00
0

@Twissted Оооо, спасибо, что указали на это. Огромная оплошность с моей стороны. Диктант был плохим выбором. Немедленно исправлю.

Twissted
8 апреля 2018 в 01:02
0

Диктатор работает, просто я еще не научился. И это прекрасно работает, если вы начинаете с Пять > Четыре > Три > Два > Один. Я поменял местами и проверил.

Aran-Fey
8 апреля 2018 в 01:05
0

@Twissed Нет, словари по своей сути неупорядочены. Если это работает, это просто совпадение, что значения оказались правильно упорядоченными. Список в данном случае является правильным выбором. (Начиная с python 3.6 словари упорядочены, но это деталь реализации. Начиная с python 3.7, словари официально поддерживают порядок.)

Twissted
8 апреля 2018 в 01:10
0

В данном случае на меня работает случайность. Python невероятно запутан, логически я понимаю, как что-то должно работать. Но реализация - это что-то свое. Еще раз спасибо :)