0

I have a tuple that looks like:
t=(('a','b'),('a','c','d','e'),('c','d','e'))

I need to rearrange it so I have a new tuple that will look like:
t2=(('a','b'),('a','c'),('c','d'),('d','e'),('c','d'),('d','e'))

Basically the new tuple takes pairs (of 2) from each element of the old tuple. But I am not sure how to get started. Thanks for your help.

pushkin
  • 9,575
  • 15
  • 51
  • 95
CWeeks
  • 407
  • 1
  • 5
  • 15

4 Answers4

1

Use a generator expression with zip to pair and convert to a tuple at the end:

>>> t = (('a','b'),('a','c','d','e'),('c','d','e'))
>>> tuple((x) for tupl in t for x in zip(tupl, tupl[1:]))
(('a', 'b'), ('a', 'c'), ('c', 'd'), ('d', 'e'), ('c', 'd'), ('d', 'e'))                                               
Austin
  • 25,759
  • 4
  • 25
  • 48
0

Try this out :

 tuple([(t[i][j],t[i][j+1]) for i in range(len(t)) for j in range(len(t[i])-1)])
#[('a', 'b'), ('a', 'c'), ('c', 'd'), ('d', 'e'), ('c', 'd'), ('d', 'e')]

You can also try another way. If the problem is reduced to do this for one tuple alone :

def pairs(my_tuple):
    return [(my_tuple[i],my_tuple[i+1]) for i in range(len(my_tuple)-1)]

Then this can be mapped for all the tuples

tuple(sum(list(map(pairs,t)),[]))
#(('a', 'b'), ('a', 'c'), ('c', 'd'), ('d', 'e'), ('c', 'd'), ('d', 'e'))

Explanation :

map(pairs,t)       : maps the function pairs for every element in tuple t
list(map(pairs,t)) : output of the above
                      But as a nested list 
                      [[[('a', 'b')], [('a', 'c'), ('c', 'd'), ('d', 'e')],...]
sum(list(...),[])   : Flattens out this nested list for the desired output
Sruthi
  • 2,908
  • 1
  • 11
  • 25
  • @CWeeks Made some new additions too :) – Sruthi May 04 '18 at 02:50
  • @SruthiV `tuple(sum(list(map(pairs,t)),[]))` is not a very efficient way to flatten this: `tuple(y for x in map(pairs, t) for y in x)` would do the same without creating lots of intermediate lists. – AChampion May 05 '18 at 00:12
0

You can use this easy to understand code:

t = (('a','b'),('a','c','d','e'),('c','d','e'))
t2 = []
for i in t:
    for j in range(len(i)-1):
           t2.append((i[j], i[j+1]))
t2 = tuple(t2)

Obviously it isn't very optimized like other answers but for an easy understanding it will be perfect.

That is something equivalent to:

t2 = tuple((i[j], i[j+1]) for i in t for j in range(len(i)-1))

That is a generator expression, something quite similar to list comprehension (it use brackets instead of square brackets) and they basically do similar things, or at least in basic codes like this one. I still don't understand very well their differences but the generators are one-time fasters while the list comprehension are slower but reusable...

Nevermind: the generator means:

t2 = tuple(...) # Make with the result array a tuple, otherwise it will be a list.
for i in t # Iterate over each item of t, they will by called i.
for i in t for j in range(len(i)) # Iterate over each item of t --called--> i and then iterate over the range(len(i)) --called--> j. 
(i[j], i[j+1]) for i in t for j in range(len(i)) # The same as before but each time we get a new j (each time the second loop iterate) do --> (i[j], i[j+1])

I know, make two generator/list expression/comprehension on the same line is strange. I always look at an answer like this one to remember how to do that.

My old answer was:

t = (('a','b'),('a','c','d','e'),('c','d','e'))
t2 = []
for i in t:
    for j in range(len(i)):
        if j < len(i) - 1:
           t2.append((i[j], i[j+1]))
t2 = tuple(t2)

But I notice that adding a -1 to the len() of the loop I can avoid that line, because I won't never get an out of index error.

Ender Look
  • 2,303
  • 2
  • 17
  • 41
0

Here's what I came up with really quick

def transform(t):
    out = []
    for tup in t:
        for i in range(0, len(tup) - 1):
            out.append((tup[i], tup[i+1]))
    return tuple(out)