#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)])