2009-09-15 8 views
2

Je suis un débutant et à la recherche pour le Zen du koan Python :) Aujourd'hui a été de trouver le moyen le plus Pythonesq pour résoudre le problème suivant:ordre de commutation Python d'éléments

Permuter les lettres d'une paire de chaînes, par exemple

input: 'abcdefgh' 
output: 'badcfehg' 
+4

Woohoo questions devoirs! – geowa4

Répondre

13

Je vais pour:

s="abcdefgh" 
print "".join(b+a for a,b in zip(s[::2],s[1::2])) 

s [start: end: étape] prend toutes les lettres step'th, zip les jumelle par paires, la boucle les swaps, et join vous renvoie une chaîne.

+0

Merde, je tapais juste ceci moi-même! – Will

1

Depuis en Python, chaque chaîne est aussi une itérative, itertools est très pratique ici.

En plus des fonctions qu'offre l'outil, la documentation fournit également de nombreuses recettes.

from itertools import izip_longest 

# From Python 2.6 docs 
def grouper(n, iterable, fillvalue=None): 
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return izip_longest(fillvalue=fillvalue, *args) 

Maintenant, vous pouvez utiliser le mérou pour regrouper la chaîne par paires, puis d'inverser les paires, puis les rejoindre dans une chaîne.

pairs = grouper(2, "abcdefgh") 
reversed_pairs = [''.join(reversed(item)) for item in pairs] 
print ''.join(reversed_pairs) 
5
''.join(s[i+1] + s[i] for i in range(0,len(s),2)) 

Oui, je sais qu'il est moins pythonique pour l'utilisation de gamme, mais il est court, et je ne doute pas de l'expliquer pour vous de savoir ce qu'il fait.

+2

Si vous le remplacez par '' .join (s [i] + s [i-1] pour i dans la plage (1, len (s), 2)) vous évitez l'exception sur l'entrée de longueur impaire, fwiw. –

+0

pourquoi range() moins pythonique? –

+0

matt: l'utilisation d'indices pour obtenir des éléments d'une séquence est souvent considérée comme non-pythonique. –

6

mon préféré faire des choses par paires:

def pairwise(iterable): 
    it = iter(iterable) 
    return zip(it, it) # zipping the same iterator twice produces pairs 

output = ''.join(b+a for a,b in pairwise(input)) 
+1

vraiment COOL! :-D – fortran

+0

+1 pour utiliser les itérateurs pour ce qu'ils font bien - garder la trace de la séquence "curseur" – u0b34a0f6ae

+2

'n_tuples = (lambda itérable, n: zip (* [iter (iterable)] * n))' – u0b34a0f6ae

2

Je viens de remarquer que aucun des réponses existantes fonctionnent si la longueur de l'entrée est impair. La plupart des réponses perdent le dernier caractère. Ma réponse précédente jette une exception.

Si vous voulez juste le dernier caractère cloué sur la fin, vous pourriez faire quelque chose comme ceci:

print "".join(map(lambda a,b:(b or '')+a, s[::2], s[1::2])) 

ou 2.6 et versions ultérieures:

print "".join(b+a for a,b in izip_longest(s[::2],s[1::2], fillvalue='')) 

Ceci est basé sur la réponse de Anthony Towns , mais utilise map ou izip_longest pour s'assurer que le dernier caractère d'une chaîne de longueur impaire n'est pas supprimé. Le bit (b or '') dans la version map est de convertir les None que map en ''.

0

Cela peut sembler un peu effrayant, mais je pense que vous devriez apprendre beaucoup déchiffrer le langage suivant:

s = "abcdefgh" 
print ''.join(b+a for a,b in zip(*[iter(s)]*2))