2011-01-05 20 views
13

Voglio scambiare ogni coppia di caratteri in una stringa. '2143' diventa '1234', 'badcfe' diventa 'abcdef'.Qual è il modo più semplice per scambiare il char in una stringa con Python?

Come posso farlo in Python?

+0

srsly, non di nuovo. – gruszczy

+2

Almeno il q è chiaro ora. Anche se sarebbe più chiaro se la stringa originale fosse "foobar" e il risultato "ofbora" - sembra ancora una sorta di ordinamento, ma ora sappiamo che non lo è! – Spacedman

+1

Giù votato per ripubblicare la stessa domanda. * sigh * – clifgriffin

risposta

13

oneliner:

>>> s = 'badcfe' 
>>> ''.join([ s[x:x+2][::-1] for x in range(0, len(s), 2) ]) 
'abcdef' 
  • s [x: x + 2] restituisce fetta stringa da xx + 2; è sicuro per le len dispari.
  • [:: - 1] inverte la stringa in Python
  • intervallo (0, len (s), 2) restituisce 0, 2, 4, 6 ...mentre x < len (s)
1

Ecco un modo ...

>>> 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' 
>>> 
+0

c'è un 's' nel tuo args e no 's' nel tuo corpo! risolto in una modifica. – Spacedman

+1

s = '2143' non '2134' hai usato var indefinito c – cocobear

+1

Questo scambio solo il primo carattere, e se poi vuoi scambiare tutto devi dividere e unire la stringa per len (s)/2 volte. –

0

Vuoi le cifre ordinati? O stai scambiando cifre indicizzate pari/dispari? Il tuo esempio è totalmente poco chiaro.

Ordina:

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

s è ora '1234'. Il trucco è qui che la lista (stringa) la spezza in caratteri.

+1

Come nota, è più conciso solo fare ''' .join (ordinato (s))' e altrettanto chiaro. –

+0

mi dispiace per quello. Voglio scambiare ogni due caratteri nella stringa. – cocobear

+0

Ho sempre dimenticato ordinati (x)! Grazie. – Spacedman

1

loop oltre la lunghezza di corda da due e swap:

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) 

dando:

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

e non riesce sulle stringhe di lunghezza dispari con un'eccezione IndexError.

6

Il solito modo di scambiare per oggetti in Python è:

a, b = b, a 

così sembrerebbe a me che basta fare lo stesso con una fetta esteso. E 'un po' complicato perché le stringhe non sono mutabili modo da avere per convertire in una lista e poi di nuovo a una stringa, ma quello che farei è:

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

ValoreErrore per len dispari? –

+1

Sfortunatamente, non funzionerà su stringhe di lunghezza non uniforme. –

+0

Paulo o Fabian, cosa vorresti che succedesse per un input non valido oltre a lanciare un'eccezione? – Duncan

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

o

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

o se la stringa può avere una lunghezza dispari:

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

si noti che questo non funzionerà con le vecchie versioni di Python (se non sto sbagliando Olde r di 2,5).

Il benchmark è stato eseguito su python-2.7-8.fc14.1.x86_64 e una CPU Core 2 Duo 6400 con s=''*4.

+1

per len dispari (s) il primo dà 'IndexError: string index out of range', il secondo chops last char. –

+1

@paulo: e quali sono i requisiti dell'OP per le stringhe di lunghezza dispari? – SilentGhost

+0

@Paulo Scardine: hai ragione, ma la domanda non era abbastanza specifica. –

0

Come così:

>>> 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' 
0
re.sub(r'(.)(.)',r"\2\1",'abcdef1234') 

Tuttavia Re è un po 'lento.

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

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

Se le prestazioni o l'eleganza non è un problema, e si desidera semplicemente chiarezza e hanno il lavoro fatto poi semplicemente utilizzare questo:

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

Questo permette di scambiare o semplicemente sostituire caratteri o stringa. Per esempio, per scambiare 'ab' < -> 'de' in un testo:

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

Non sarà estremamente limitato nell'applicazione? –

2

Non c'è bisogno di fare una lista. Le seguenti opere per archi, anche di lunghezza:

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

cosa succede se la stringa ha una lunghezza dispari? –

0

più un modo:

>>> s='123456' 
>>> ''.join([''.join(el) for el in zip(s[1::2], s[0::2])]) 
'214365' 
0
>>> 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 
0
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 
-1
#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) 
+0

Benvenuto in Stack Overflow! Sebbene questo snippet di codice possa risolvere la domanda, compresa una spiegazione di * come * e * perché * questo risolve il problema [potrebbe davvero aiutare] (// meta.stackexchange.com/q/114762) per migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro, non solo la persona che chiede ora! Si prega di [modificare] la risposta per aggiungere una spiegazione e fornire un'indicazione di quali limitazioni e ipotesi si applicano. –

Problemi correlati