Python control order

I'm a beginner and looking for Zen of Python :) Today koan was finding the most Pythonesq way to solve the following problem:

Reassign letters of a string in pairs, for example

input:  'abcdefgh'
output: 'badcfehg'

      

+2


source to share


6 answers


I would go for:

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

      



s [start: end: step] takes each step letter, zip matches them in pairs, the loop changes them, and the join returns a string.

+13


source


my personal favorite is doing things in pairs:



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

      

+6


source


''.join(s[i+1] + s[i] for i in range(0,len(s),2))

      

Yes, I know it's less pythonic for range usage, but it's short and I probably shouldn't have to explain it to you in order to figure out what it does.

+5


source


I just noticed that none of the existing answers work if the input length is odd. Most answers lose the last character. My previous answer throws an exception.

If you just want the last character to be attached to the end, you could do something like this:

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

      

or in 2.6 and later:

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

      

This is based on Anthony Townes' answer, but uses either map

or izip_longest

to make sure the last character in an odd length string is not discarded. The bit (b or '')

in the version map

is to convert None

which map

pads to ''

.

+2


source


Since every line is iterable in Python too, itertools comes in handy here.

In addition to the functions provided by itertools, the documentation also contains many recipes.

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)

      

Now you can use grouper to group a string into pairs, then reverse the pairs, and then concatenate them back into a string.

pairs = grouper(2, "abcdefgh")
reversed_pairs = [''.join(reversed(item)) for item in pairs]
print ''.join(reversed_pairs)

      

+1


source


This may sound a little scary, but I think you will recognize a lot of deciphering for the following idiom:

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

      

0


source







All Articles