Что не так со вторым циклом for

Я хочу чтобы чётные и не чётные буквы поменялись местами

proverb ='Программисты - это устройства, преобразующие кофеин в код.'
new_proverb=[]
for i in proverb[1::2]:
    new_proverb+=i
    for a in proverb[::2]:
        new_proverb+=a

new_proverb="".join(new_proverb)
print(new_proverb)
>>>  
рПормит  т срйта рорзюи оенвкдгПормит  т срйта рорзюи оенвкдаПормит  т срйта рорзюи оенвкдмПормит  т срйта рорзюи оенвкдсПормит  т срйта рорзюи оенвкдыПормит  т срйта рорзюи оенвкд-Пормит  т срйта рорзюи оенвкдэПормит  т срйта рорзюи оенвкдоПормит  т срйта рорзюи оенвкдуПормит  т срйта рорзюи оенвкдтПормит  т срйта рорзюи оенвкдоПормит  т срйта рорзюи оенвкдсПормит  т срйта рорзюи оенвкдвПормит  т срйта рорзюи оенвкд,Пормит  т срйта рорзюи оенвкдпПормит  т срйта рорзюи оенвкдеПормит  т срйта рорзюи оенвкдбПормит  т срйта рорзюи оенвкдаПормит  т срйта рорзюи оенвкдуПормит  т срйта рорзюи оенвкдщПормит  т срйта рорзюи оенвкдеПормит  т срйта рорзюи оенвкдкПормит  т срйта рорзюи оенвкдфПормит  т срйта рорзюи оенвкдиПормит  т срйта рорзюи оенвкд Пормит  т срйта рорзюи оенвкд Пормит  т срйта рорзюи оенвкдоПормит  т срйта рорзюи оенвкд.Пормит  т срйта рорзюи оенвкд

Ответы (4 шт):

Автор решения: artaxerx

Сейчас вы после каждого символа с чётной позиции записываете все символы с нечётных позиций, поскольку второй цикл из-за отступов оказывается вложен в первый. Если просто хотите поменять их местами, то логика должна быть примерно такая:

is_even = len(proverb) % 2 == 0
# поскольку шагаем по парам, может остаться лишний символ в конце
N = len(proverb) if is_even else len(proverb) - 1
for i in range(0, N, 2):
    new_proverb += proverb[i + 1] + proverb[i]
# добавляем последний символ, если нужно
if not is_even:
    new_proverb += proverb[-1]

Если же хотите менять местами только буквы, то уже нужен более хитрый алоритм

→ Ссылка
Автор решения: Vladimir T
proverb2 = {}
for i in range(len(proverb)):
     proverb2[i-1 if i%2 else i+1]=proverb[i]

''.join([proverb2[key] for key in sorted(proverb2)])
→ Ссылка
Автор решения: Евгений

Можно "сшить" вместе два среза с помощью функции zip, а потом вывести их, склеив буквы вместе

# тестирование на строке с нечётным кол-вом символов
>>> s = 'Программисты - это устройства, преобразующие кофеин в коды.'
>>> z = zip(list(s[1::2]) + [''], s[::2])
>>> ''.join(''.join(letter for letter in pare) for pare in z)
'рПгоарммсиыт- э оту тсорсйвт,ап ербоарузщюеик фоие н вокыд.'

# тестирование на строке с чётным кол-вом символов
>>> s = 'Программисты - это устройства, преобразующие кофеин в код.'
>>> z = zip(list(s[1::2]) + [''], s[::2])
>>> ''.join(''.join(letter for letter in pare) for pare in z)
'рПгоарммсиыт- э оту тсорсйвт,ап ербоарузщюеик фоие н вок.д'

Объяснение list(s[1::2]) + ['']:

  1. Если в строке чётное кол-во символов, то в list(s[1::2]) + [''] будет ровно на один элемент больше, чем в list(s[::2]), и функция zip выбросит лишний элемент (ту самую пустую строку)

  2. Если в строке нечётное кол-во символов, то в list(s[1::2]) + [''] будет столько же элементов, сколько и в list(s[::2]), но последний элемент первого списка будет пустой строкой. Пустая строка ставится в соответствие последнему символу нечётной строки и никак не влияет на результат склейки ('' + 'a' == 'a')

Таким образом мы компенсируем возможно существующий нечётный символ в конце, искусственно ставя ему в соответствие пустую строку, чтобы zip не выбросила этот последний символ.

→ Ссылка
Автор решения: Artem

Попробуйте так, должно сработать:

proverb = 'Программисты - это устройства, преобразующие кофеин в код.'
new_proverb = ''
for i in range(0, len(proverb)-1, 2):
    new_proverb += proverb[i +1] + proverb[i]
print(new_proverb)
→ Ссылка