Каков самый простой способ обмена char в строке с Python?

Я хочу поменять каждую пару символов в строке. '2143' становится '1234', 'badcfe' становится 'abcdef'.

Как я могу сделать это в Python?

Ответы

Ответ 1

Oneliner:

>>> s = 'badcfe'
>>> ''.join([ s[x:x+2][::-1] for x in range(0, len(s), 2) ])
'abcdef'
  • s [x: x + 2] возвращает строковый срез из x в x + 2; он безопасен для нечетных len (s).
  • [:: - 1] меняет строку в Python
  • диапазон (0, len (s), 2) возвращает 0, 2, 4, 6... в то время как x < Len (ы)

Ответ 2

Обычный способ поменять два элемента в Python:

a, b = b, a

Так что мне кажется, что вы бы сделали то же самое с расширенным срезом. Однако, это немного сложно, потому что строки не являются изменяемыми; поэтому вы должны преобразовать в список, а затем вернуться к строке.
Поэтому я бы сделал следующее:

>>> s = 'badcfe'
>>> t = list(s)
>>> t[::2], t[1::2] = t[1::2], t[::2]
>>> ''.join(t)
'abcdef'

Ответ 3

Вот один из способов...

>>> s = '2134'
>>> def swap(c, i, j):
...  c = list(c)
...  c[i], c[j] = c[j], c[i]
...  return ''.join(c)
...
>>> swap(s, 0, 1)
'1234'
>>>

Ответ 4

Перебирать длину строки по двум и свопам:

def oddswap(st):
    s = list(st)
    for c in range(0,len(s),2):
        t=s[c]
        s[c]=s[c+1]
        s[c+1]=t

    return "".join(s)

даяние:

>>> s
'foobar'
>>> oddswap(s)
'ofbora'

и сбой в строках с нечетной длиной с исключением IndexError.

Ответ 5

''.join(s[i+1]+s[i] for i in range(0, len(s), 2)) # 10.6 usec per loop

или

''.join(x+y for x, y in zip(s[1::2], s[::2])) # 10.3 usec per loop

или если строка может иметь нечетную длину:

''.join(x+y for x, y in itertools.izip_longest(s[1::2], s[::2], fillvalue=''))

Обратите внимание, что это не будет работать со старыми версиями Python (если я не ошибаюсь старше 2.5).

Тест был запущен на python-2.7-8.fc14.1.x86_64 и процессоре Core 2 Duo 6400 с s='0123456789'*4.

Ответ 6

Если производительность или элегантность не являются проблемой, и вы просто хотите ясности и выполняете свою работу, просто используйте это:

def swap(text, ch1, ch2):
    text = text.replace(ch2, '!',)
    text = text.replace(ch1, ch2)
    text = text.replace('!', ch1)
    return text

Это позволяет вам менять или просто заменять символы или подстроку. Например, чтобы поменять 'ab' ↔ 'de' в тексте:

_str = "abcdefabcdefabcdef"
print swap(_str, 'ab','de') #decabfdecabfdecabf

Ответ 7

Нет необходимости составлять список. Следующие строки для строк с четными строками:

r = ''
for in in range(0, len(s), 2) :
  r += s[i + 1] + s[i]
s = r

Ответ 8

Вы хотите отсортировать цифры? Или вы меняете нечетные/даже индексированные цифры? Ваш пример совершенно неясен.

Сортировка:

s = '2143'
p=list(s)
p.sort()
s = "".join(p)

s теперь "1234". Фокус в том, что список (строка) разбивает его на символы.

Ответ 9

Так же:

>>> s = "2143658709"
>>> ''.join([s[i+1] + s[i] for i in range(0, len(s), 2)])
'1234567890'

>>> s = "badcfe"
>>> ''.join([s[i+1] + s[i] for i in range(0, len(s), 2)])
'abcdef'

Ответ 10

re.sub(r'(.)(.)',r"\2\1",'abcdef1234')

Однако re немного медленнее.

def swap(s):
    i=iter(s)
    while True:
        a,b=next(i),next(i)
        yield b
        yield a

''.join(swap("abcdef1234"))

Ответ 11

Еще один способ:

>>> s='123456'
>>> ''.join([''.join(el) for el in zip(s[1::2], s[0::2])])
'214365'

Ответ 12

>>> import ctypes
>>> s = 'abcdef'
>>> mutable = ctypes.create_string_buffer(s)
>>> for i in range(0,len(s),2):
>>>     mutable[i], mutable[i+1] = mutable[i+1], mutable[i]
>>> s = mutable.value
>>> print s
badcfe

Ответ 13

def revstr(a):
    b=''
    if len(a)%2==0:
        for i in range(0,len(a),2):
            b += a[i + 1] + a[i]
        a=b
    else:
        c=a[-1]
        for i in range(0,len(a)-1,2):
            b += a[i + 1] + a[i]
        b=b+a[-1]
        a=b
    return b
a=raw_input('enter a string')
n=revstr(a)
print n

Ответ 14

Более общий ответ... вы можете сделать любой одиночный попарный обмен с кортежами или строками следующим образом:

# item can be a string or tuple and swap can be a list or tuple of two
# indices to swap
def swap_items_by_copy(item, swap):
   s0 = min(swap)
   s1 = max(swap)
   if isinstance(item,str):
        return item[:s0]+item[s1]+item[s0+1:s1]+item[s0]+item[s1+1:]
   elif isinstance(item,tuple):
        return item[:s0]+(item[s1],)+item[s0+1:s1]+(item[s0],)+item[s1+1:]
   else:
        raise ValueError("Type not supported")

Затем вы можете вызвать его следующим образом:

>>> swap_items_by_copy((1,2,3,4,5,6),(1,2))
(1, 3, 2, 4, 5, 6)
>>> swap_items_by_copy("hello",(1,2))
'hlelo'
>>> 

К счастью, python предоставляет пустые строки или кортежи для случаев, когда индексы ссылаются на несуществующие фрагменты.

Ответ 15

#Works on even/odd size strings
str = '2143657'
newStr = ''
for i in range(len(str)//2):
    newStr += str[i*2+1] + str[i*2]
if len(str)%2 != 0:
    newStr += str[-1]
print(newStr)

Ответ 16

#Think about how index works with string in Python,
>>> a = "123456"
>>> a[::-1]
'654321'