Делать каждую вторую букву в строке прописной с помощью метода, отличного от index() в Python?

#python

#python

Вопрос:

 def myfunc(mylist = str):
mystring = ''
for x in mylist:
    if mylist.index(x) % 2 == 0:
        mystring = mystring   x.lower()
    else:
        mystring = mystring   x.upper()
return mystring
print(myfunc('committee')) #Doesn't work
print(myfunc('ilovehoney')) #Does work
  

Я считаю, что ошибка в моем коде — это index(), поскольку он не распознает повторяющиеся буквы в строке. Кто-нибудь знает другой метод, который я мог бы использовать? Вывод в первом примере — ‘cOmmiTTEE’, но должен быть ‘cOmMiTtEe’, в то время как вывод во втором примере, как я и предполагал, ‘iLoVeHoNeY’. Хотя я не уверен, почему моя функция внезапно работает во втором примере. Спасибо за помощь.

Комментарии:

1. .index() ищет ПЕРВОЕ совпадение с x . Итак, если у вас есть повторяющиеся символы, ваша текущая функция не будет работать. Попробуйте: «eeeeeeeeeee», например.

2. Я вижу, что индекс не является хорошим выбором для повторного использования символов, понял. Спасибо за объяснение.

Ответ №1:

enumerate() дает вам индекс текущего цикла:

 s = 'committee'
"".join([x.upper() if i%2!=0 else x for i,x in enumerate(s)])
Out[4]: 'cOmMiTtEe'
  

Комментарии:

1. Спасибо за ваш ответ. К сожалению, я не слишком знаком с пониманием списка, поэтому я пока стараюсь избегать этого, но, спасибо, то, что вы написали, выглядит действительно интересно. К сожалению, у меня нет репутации 15, поэтому я не могу повысить ваш ответ, но я сделаю это, как только получу репутацию.

Ответ №2:

Вы можете использовать enumerate для получения индекса и значения из итерируемого:

 for idx, x in enumerate(mylist):
    if idx % 2 == 0:
        mystring = mystring   x.lower()
    else:
        mystring = mystring   x.upper()
  

Комментарии:

1. Это сработало, спасибо за вашу помощь. Теперь мне пора выяснить, что делает enumerate и как работают несколько переменных в цикле for. К сожалению, у меня нет репутации 15, поэтому я не могу повысить ваш ответ, но я сделаю это, как только получу репутацию.

2. @MMOToaster В принципе, enumerate возвращает кортеж (index, value) для каждого элемента в списке, который распаковывается idx, x в коде, которым я поделился с вами. Подробнее об этом вы можете прочитать здесь: docs.python.org/3/library/functions.html#enumerate

3. На самом деле ссылка в приведенном выше посте может быть немного запутанной. Попробуйте вот это: geeksforgeeks.org/enumerate-in-python

4. А, понятно. Не совсем понял, что вы только что написали, но я посмотрю ссылку, которую вы опубликовали, спасибо за вашу помощь.

5. Спасибо за ссылки, я прочитаю их обе и попытаюсь их понять.

Ответ №3:

Вам вообще не нужно знать точный индекс. Просто переверните флаг: нет-да-нет-да-нет-и т.д.

 def myfunc(mylist):
    mystring = ''
    upper = False
    for x in mylist:
        mystring = mystring   (x.upper() if upper else x.lower())
        upper = not upper
    return mystring
  

Пожалуйста, обратите внимание, что таким образом создавать строку неэффективно (дайте Google «Shlemiel the painter»). Улучшенная версия:

 def myfunc(mylist):
    mychars = []
    upper = False
    for x in mylist:
        mychars.append(x.upper() if upper else x.lower())
        upper = not upper
    return ''.join(mychars)
  

Комментарии:

1. Спасибо за ваш ответ. Эта процедура «нет-да-нет-да» кажется простейшим способом решения задачи с переключением флага. Я думаю, что теперь я буду использовать это для будущих подобных задач, спасибо. Хотя я не понимаю, почему первый код неэффективен, я дам прочитать ‘Shlemiel the painter’. К сожалению, у меня нет репутации 15, поэтому я не могу повысить ваш ответ, но я сделаю это, как только получу репутацию.

2. Я рад, что смог немного помочь. Не беспокойтесь о преимуществах.