#python #string
Вопрос:
Я должен написать функцию, которая получает строку и возвращает эту строку с символами между "*"
в верхнем регистре , например, учитывая эту строку: “I want *this text* to be uppercase”
, она возвращает : “I want THIS TEXT to be uppercase”
. Вот код, который я написал:
l = [] def func(s): inside = False for i in s: if i == "*" and not inside: inside = True while inside: if i == "*": inside = False else: i.upper() l.append(i) print(s)
Когда я запускаю программу, она распечатывает текст без каких-либо изменений.
Что я делаю не так?
Комментарии:
1. Строка, на которую ссылается s , никогда не изменяется в вашем коде
Ответ №1:
Во-первых, эта функция ничего не делает s
, поэтому print(s)
будет выводить все, что было введено, без изменений.
Во — вторых, while inside
цикл должен находиться вне этого if
оператора-прямо сейчас доступ к нему возможен только тогда, когда i
он помечен звездочкой. Уменьшите отступ всего блока на единицу и измените while inside
значение на if inside
— таким образом, этот код выполняется для всех значений i
, когда inside
верно.
Далее, вам нужен способ подать сигнал, когда будет достигнута вторая звездочка, или третья, и так далее. Как насчет того, чтобы вместо присвоения inside
значения True
if i
является звездочкой и inside
имеет значение False, вы меняете значение inside
при каждом достижении звездочки?
if i == '*': inside = not inside
Это сводит на нет любую необходимость возиться с изменениями inside
во второй части вашего кода — это помещает всю определяющую логику «я внутри/я снаружи» в одно место.
Затем вы объявили список l
за пределами области действия функции, и, похоже, вы хотите добавить в него отредактированные символы, чтобы в конце концов нужный вам ответ оказался в этом списке. Но вы хотите, чтобы ваш ответ был в строке, а не в списке, и обычно не рекомендуется объявлять список в глобальной области, а затем редактировать его во время вызова функции (если вы вызовете функцию более одного раза, список станет беспорядочным!). Объявите пустую строку l = ''
в начале функции, а затем вместо добавления к ней символов вы можете добавить их с помощью =
оператора.
Вам также необходимо убедиться, что вы добавляете версию в верхнем регистре l = i.upper()
или обычную версию, l = i
в зависимости от того , верно это или нет inside
. Вы можете поместить весь код после if i == '*'
строки в else
оператор, чтобы перехватить все случаи, i
не отмеченные звездочкой.
Собрав все это вместе, ваша функция может выглядеть примерно так:
def func(s): l = '' # the string that will be returned (the result of the function) inside = False for i in s: if i == "*": # flip value of inside whenever you see an asterisk inside = not inside else: # otherwise, add i to the result if inside: l = i.upper() # uppercase if between two asterisks else: l = i # unchanged if not return l # and return the modified string
Затем, чтобы протестировать функцию:
my_string = "I want *this text* to be uppercase" my_string_modified = func(my_string) print(my_string) print(my_string_modified)
Выход:
I want *this text* to be uppercase I want THIS TEXT to be uppercase
Безусловно, есть более «продвинутые» способы сделать это, как указано в других ответах на этот пост, но я надеюсь, что этот ответ помог прояснить, что происходит не так в вашем коде, как это исправить и каковы некоторые рекомендации, когда вы пишете подобные вещи. Написание кода таким образом, на мой взгляд, действительно хороший способ понять, как можно разрабатывать и реализовывать алгоритмические процессы.
Ответ №2:
Я думаю, вы пытались сделать это более сложным, чем оно есть на самом деле. Вам нужно найти индекс обеих звездочек. Из этого вы можете получить три фрагмента исходной строки и применить функцию upper() к фрагменту между звездочками. Обратите внимание, что этот код завершится ошибкой, если в строке будет меньше двух звездочек.
def dotricks(s): i = s.index('*') j = s.index('*', i i) return s[0:i] s[i 1:j].upper() s[j 1:] print(dotricks('I want *this text* to be uppercase'))
Ответ №3:
Вы не изменяете строку в своем коде. В этом правке ниже я присвоил буквы строки новой переменной. И раньше continue
пропускал «*». Кроме того, в конце вашего приложения вы получите список букв, которые вам нужно использовать .join()
для объединения.
Попробуйте внести это изменение в свой код, протестированный и работающий:
l = [] def func(s): inside = False temp = "" for i in s: if i == "*" and not inside: inside = True continue if inside: if i == "*": inside = False continue else: temp = i.upper() else: temp = i l.append(temp) new_string = "".join(l) print(new_string) return new_string func("I want *this text* to be uppercase")
Комментарии:
1. Вам не нужно объявлять
temp
пустую строку в начале функции
Ответ №4:
Здесь есть несколько проблем:
- Вы ничего не возвращаете внутри своей функции
- Ваш
while
цикл бессмыслен, так какi
он не увеличивается внутри него - Вам необходимо назначить
i
i.upper()
- Вам нужно передать входные данные в список
Исправленный код будет выглядеть следующим образом:
l = [] def func(s): inside = False for i in s: if i == "*" and not inside: inside = True while inside: if i == "*": inside = False else: i.upper() if i != "*": l.append(i) return l
Комментарии:
1. Этот код возвращает список, содержащий ограничивающие звездочки. Я не уверен, что это то, что было нужно
2. @BrutusForcus Я отредактировал, чтобы удалить звездочки.
Ответ №5:
Разделив строку на символ *
, тогда запись в верхнем регистре будет нечетной, а затем соединится вместе. Предполагается, что их всегда четное число *
, поэтому их следует считать своего рода зарезервированным символом.
s = "I want *this text* to be uppercase and *this* as well" print(' '.join((j.upper() if i%2!=0 else j for i, j in enumerate(s.split('*')))))
Выход
I want THIS TEXT to be uppercase and THIS as well
Ответ №6:
Я бы использовал мощность re
модуля:
import re st = "I want *this text* to be uppercase and *this one*" v = re.findall("*(.*?)*", st) for s in v: st = st.replace(f'*{s}*', s.upper()) print(st)
Выход:
gt;gt;gt; I want THIS TEXT to be uppercase and THIS ONE
В любом случае, отредактируйте свой код заново:
def func(s): l = [] inside = False for i in s: if i == "*": inside = not inside # switch inside on/off when * is found if inside: i = i.upper() # upper the character if inside == True l.append(i) return l
Если вы посмотрите на свой исходный код, часть проблемы заключается в следующей логике:
if i == "*" and not inside: inside = True # inside is set to True when * is found.... while inside: if i == "*": inside = False # and immediately set to False again!
Комментарии:
1. Почему бы не использовать
re.sub
напрямую?2.
re.sub("*(.*?)*", lambda x: x.group().upper(), st)
заменил бы текст в том же вызове.3. @HampusLarsson, ваша замена шаблона не возвращает то, что хочет пользователь. Эти * все еще там
4.
re.sub("*(.*?)*", lambda x: x.group().upper().strip("*"), st)
Тогда используй это.