Как пропустить итерацию в цикле for?
Пробовал пропустить итерацию с помощью оператора continue. Но, видимо, он не подходит. Задача описана ниже в комментарии к коду:
# Задача программы:
# - переводить любой текст в следующий формат: "сЛуЧаЙнЫй ТеКсТ"
# - т.е., каждая новая буква в слове должна отличаться в регистре от предыдущей
# - пробелы пропускаются
user_text = "любой случайно набранный текст"
Сначала я хотел написать что-то типа:
for i in user_text:
i = i.upper() # метод upper() выносит слова в верхний регистр
continue
Но потом понял, что это не верно.
Ответы (5 шт):
Можно так:
user_text = 'любой, дАжЕ "СЛУЧАЙНО" набраный ТЕКСТ'
i = 0
simbols_list = []
for s in user_text.lower():
if s.isalpha():
simbols_list.append(s if not i%2 else s.upper())
i += 1
else:
simbols_list.append(s)
new_text = ''.join(simbols_list)
в new_text будет:
лЮбОй, ДаЖе "СлУчАйНо" НаБрАнЫй ТеКсТ
Выполняется требование "каждая новая буква в слове должна отличаться в регистре от предыдущей", пропускает не только пробелы, но и знаки препинания (любую "небукву"). Спасибо Vadim.Sharoikin за уточнение!
user_text = "любой случайно набраный текст"
user_text2 = ""
for i, s in enumerate(user_text):
if s != " ":
user_text2 += s.upper() if i % 2 == 0 else s.lower()
else:
user_text2 += " "
print(user_text2)
# ЛюБоЙ СлУчАйНо нАбРаНыЙ ТеКсТ
Более короткая запись
user_text = "любой случайно набраный текст"
print("".join([s.upper() if s != " " and i % 2 == 0 else s.lower() for i, s in enumerate(user_text)]))
# ЛюБоЙ СлУчАйНо нАбРаНыЙ ТеКсТ
В Python строки - неизменяемый тип данных, поэтому изменить посимвольно не получится. Можно сделать через новую строку:
# Задача программы:
# - переводить любой текст в следующий формат: "сЛуЧаЙнЫй ТеКсТ"
# - т.е., каждая новая буква в слове должна отличаться в регистре от предыдущей
# - пробелы пропускаются
user_text = "любой случайно набранный текст"
new_user_text, i = '', 0 # итоговая строка; счетчик символов в строке, кроме пробелов
for c in user_text.lower(): # сразу привели все символы к нижнему регистру
new_user_text += c.upper() if i%2 else c # каждый второй символ приводим к верхнему регистру
i += 1 if c.isalpha() else 0 # увеличиваем счетчик символов в строке если это буква
print(new_user_text)
Можно и с continue, главное знать где применить:
text = 'Специальный выпуск сериала "Друзья" телеканала HBO Max получил официальную дату премьеры в России'
switch = False
res = []
for t in text:
if not t.isalpha():
res.append(t)
continue
if switch:
res.append(t.upper())
else:
res.append(t.lower())
switch = not switch
res = "".join(res)
print(text)
print(res)
# Специальный выпуск сериала "Друзья" телеканала HBO Max получил официальную дату премьеры в России
# сПеЦиАлЬнЫй ВыПуСк СеРиАлА "дРуЗьЯ" тЕлЕкАнАлА hBo MaX пОлУчИл ОфИцИаЛьНуЮ дАтУ пРеМьЕрЫ в РоСсИи
Пропускать итерации не нужно. В задании сказано "переводить любой текст". В том числе и такой "ПРИВЕТ" -> "пРиВеТ". Следовательно, иногда вам нужно поднимать регистр, иногда опускать. Иногда символ не должен меняться (например пробел), но и в этом случае пропускать итерацию нельзя - нужно проверить что это пробел и ничего не делать.
Если всё это учесть, то получится такой (нерабочий) код:
for i in user_text:
if not i.isalpha():
continue
# хитрое условие
if ...:
i = i.lower()
else:
i = i.upper()
Этот код работает, но ничего не делает. Строки в Питоне неизменны: сама идея, что можно отредактировать отдельные символы и вписать обратно в строку, не верна. Нужно изготавливать копию строки.
Работающий код ниже. Во-первых, регистр переключается без булевых флагов и деления с остатком. Во-вторых, это генератор. В-третьих, мои любимые скобки подряд next(cases)(c). В-четвёртых, обращение к методу класса без упоминания экземпляра (в Питоне пишут 's'.upper(), но можно и str.upper('s')):
import itertools
def mixed_case(s):
cases = itertools.cycle((str.lower, str.upper))
for c in s:
if c.isalpha():
yield next(cases)(c)
else:
yield c
for s in (
'любой случайно набранный текст',
'любой, дАжЕ "СЛУЧАЙНО" набраный ТЕКСТ',
'Специальный выпуск сериала Друзья телеканала HBO Max получил официальную дату премьеры в России'
):
print(''.join(mixed_case(s)))
$ python mixed_case.py лЮбОй СлУчАйНо НаБрАнНыЙ тЕкСт лЮбОй, ДаЖе "СлУчАйНо" НаБрАнЫй ТеКсТ сПеЦиАлЬнЫй ВыПуСк СеРиАлА дРуЗьЯ тЕлЕкАнАлА hBo MaX пОлУчИл ОфИцИаЛьНуЮ дАтУ пРеМьЕрЫ в РоСсИи
Код можно переписать компактно если воспользоваться выражением-генератором и тернарным if:
def mixed_case(s):
cases = itertools.cycle((str.lower, str.upper))
return (next(cases)(c) if c.isalpha() else c for c in s)
Пользователь TigerTV.ru предложил ипользовать map:
def mixed_case(s):
cases = itertools.cycle((str.lower, str.upper))
return map(lambda c: next(cases)(c) if c.isalpha() else c, s)