Dan
Dan

Reputation: 35443

Multiple Tuple to Two-Pair Tuple in Python?

What is the nicest way of splitting this:

tuple = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h')

into this:

tuples = [('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', 'h')]

Assuming that the input always has an even number of values.

Upvotes: 12

Views: 11658

Answers (5)

Alex Essilfie
Alex Essilfie

Reputation: 12613

I present this code based on Peter Hoffmann's answer as a response to dfa's comment.

It is guaranteed to work whether or not your tuple has an even number of elements.

[(tup[i], tup[i+1]) for i in range(0, (len(tup)/2)*2, 2)]

The (len(tup)/2)*2 range parameter calculates the highest even number less or equal to the length of the tuple so it is guaranteed to work whether or not the tuple has an even number of elements.

The result of the method is going to be a list. This can be converted to tuples using the tuple() function.

Sample:

def inPairs(tup):
    return [(tup[i], tup[i+1]) for i in range(0, (len(tup)/2)*2, 2)]

# odd number of elements
print("Odd Set")
odd = range(5)
print(odd)
po = inPairs(odd)
print(po)

# even number of elements
print("Even Set")
even = range(4)
print(even)
pe = inPairs(even)
print(pe)

Output

Odd Set
[0, 1, 2, 3, 4]
[(0, 1), (2, 3)]
Even Set
[0, 1, 2, 3]
[(0, 1), (2, 3)]

Upvotes: 0

bobince
bobince

Reputation: 536379

Here's a general recipe for any-size chunk, if it might not always be 2:

def chunk(seq, n):
    return [seq[i:i+n] for i in range(0, len(seq), n)]

chunks= chunk(tuples, 2)

Or, if you enjoy iterators:

def iterchunk(iterable, n):
    it= iter(iterable)
    while True:
        chunk= []
        try:
            for i in range(n):
                chunk.append(it.next())
        except StopIteration:
            break
        finally:
            if len(chunk)!=0:
                yield tuple(chunk)

Upvotes: -1

Andrew Jaffe
Andrew Jaffe

Reputation: 27087

Or, using itertools (see the recipe for grouper):

from itertools import izip
def group2(iterable):
   args = [iter(iterable)] * 2
   return izip(*args)

tuples = [ab for ab in group2(tuple)]

Upvotes: 6

unbeknown
unbeknown

Reputation:

zip() is your friend:

t = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h')
zip(t[::2], t[1::2])

Upvotes: 41

Peter Hoffmann
Peter Hoffmann

Reputation: 58654

[(tuple[a], tuple[a+1]) for a in range(0,len(tuple),2)]

Upvotes: 15

Related Questions