Замена каждого второго символа в строке в Python

#python #string #list

#python #строка #Список

Вопрос:

У меня следующая проблема: я хотел бы написать функцию на Python, которая, учитывая строку, возвращает строку, в которой каждая группа из двух символов поменялась местами.

Например, учитывая «ABCDEF», он возвращает «BADCFE».

Длина строки гарантированно будет четным числом.

Можете ли вы помочь мне, как это сделать в Python?

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

1. Я чувствую запах домашней работы. Что вы уже пробовали до сих пор?

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

Ответ №1:

Чтобы добавить еще одну опцию:

 >>> s = 'abcdefghijkl'
>>> ''.join([c[1]   c[0] for c in zip(s[::2], s[1::2])])
'badcfehgjilk'
 

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

1. Согласно OP: «длина строки гарантированно будет четным числом».

2. Вместо этого я бы сделал это следующим ''.join(sum(zip(s[1::2], s[::2]), ())) образом .

3. @KarlKnechtel: Я нахожу это немного запутанным из-за sum . Вероятно, это вопрос личных предпочтений, поскольку он довольно лаконичен.

4. @KarlKnechtel chain избегает необходимости добавлять все эти кортежи.

Ответ №2:

 import re
print re.sub(r'(.)(.)', r'21', "ABCDEF")
 

Ответ №3:

 from itertools import chain, izip_longest

''.join(chain.from_iterable(izip_longest(s[1::2], s[::2], fillvalue = '')))
 

Вы также можете использовать islice s вместо обычных фрагментов, если у вас очень большие строки или вы просто хотите избежать копирования.

Работает для строк нечетной длины, даже если это не является обязательным требованием вопроса.

Ответ №4:

Хотя вышеупомянутые решения действительно работают, есть очень простое решение, скажем так, в терминах «непрофессионала». Кто-то, кто все еще изучает python и string, может использовать другие ответы, но они действительно не понимают, как они работают или что делает каждая часть кода без полного объяснения плакатом, в отличие от «это работает». Ниже выполняется замена каждого второго символа в строке, и новичкам легко понять, как это работает.

Он просто перебирает строку (любой длины) на два (начиная с 0 и находя каждый второй символ), а затем создает новую строку (swapped_pair), добавляя текущий индекс 1 (второй символ), а затем фактический индекс (первый символ), например, помещается индекс 1 при индексе 0, а затем индекс 0 помещается в индекс 1, и это повторяется через итерацию строки.

Также добавлен код для обеспечения четной длины строки, поскольку он работает только для четной длины.

 string = "abcdefghijklmnopqrstuvwxyz123"

# use this prior to below iteration if string needs to be even but is possibly odd
if len(string) % 2 != 0:
    string = string[:-1]

# iteration to swap every second character in string
swapped_pair = ""
for i in range(0, len(string), 2):
    swapped_pair  = (string[i   1]   string[i])

# use this after above iteration for any even or odd length of strings
if len(swapped_pair) % 2 != 0:
    swapped_adj  = swapped_pair[-1]

print(swapped_pair)

badcfehgjilknmporqtsvuxwzy21 # output if the "needs to be even" code used
badcfehgjilknmporqtsvuxwzy213 # output if the "even or odd" code used
 

Ответ №5:

Вот отличное решение:

 def swapem (s):
    if len(s) < 2: return s
    return "%s%s%s"%(s[1], s[0], swapem (s[2:]))

for str in ("", "a", "ab", "abcdefgh", "abcdefghi"):
    print "[%s] -> [%s]"%(str, swapem (str))
 

хотя, возможно, не подходит для больших строк 🙂

Вывод:

 [] -> []
[a] -> [a]
[ab] -> [ba]
[abcdefgh] -> [badcfehg]
[abcdefghi] -> [badcfehgi]
 

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

1. Это ужасно похоже на недавний бинарный поиск моего коллеги O ( n lg n ) с нарезкой списка.

2. Рекурсия никогда не является ответом 🙂

3. @agf рекурсия — это ответ, если рекурсия — это ответ 😉

Ответ №6:

Если вы предпочитаете однострочные:

 ''.join(reduce(lambda x,y: x y,[[s[1 (x<<1)],s[x<<1]] for x in range(0,len(s)>>1)]))
 

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

1. Боже мой! Что Гвидо сделал с моим прекрасным языком? 🙂 И как я должен учить этому третьеклассника?

2. Это меня огорчает! Используйте itertools для написания сумасшедших однострочных строк, а не lambda s / reduce — это способ Python 🙂

3. Эта комбинация лямбда-редукции обычно известна как sum , что понимание списка можно легко заменить некоторым разделением и zip , а сдвиг вместо умножения / деления — это микрооптимизация, которая даже не работает.

4. Для меня сдвиг более понятен, чем 2 *, но каждому свое, я думаю. Вы правы в том sum , что я не очень часто использовал Python со времен версии 2.0, когда он был недоступен.

Ответ №7:

Вот еще одно простое решение:

 "".join([(s[i:i 2])[::-1]for i in range(0,len(s),2)])