2

I would like to functionally derive this input/output pattern:

>>> foo( (2, 3, 4, 5) )
[(2, 3), (3, 4), (4, 5)]

The idea is that the second element of the previous tuple is repeated as the first element of the next tuple. I can't get it any other way than using iterative paradigms.

For what it's worth, I'm trying to answer this question, and I also have to demonstrate functional Python at a meetup next month. So help me kill two birds with one stone please, and thanks!

Community
  • 1
  • 1
yurisich
  • 6,991
  • 7
  • 42
  • 63

2 Answers2

4
>>> f = (2, 3, 4, 5)
>>> zip(f[:-1], f[1:])
[(2, 3), (3, 4), (4, 5)]

Or, from the docs:

>>> from itertools import tee, izip
>>> def pairwise(iterable):
...     "s -> (s0,s1), (s1,s2), (s2, s3), ..."
...     a, b = tee(iterable)
...     next(b, None)
...     return izip(a, b)
... 
>>> tuple(pairwise(f))
((2, 3), (3, 4), (4, 5))
senderle
  • 145,869
  • 36
  • 209
  • 233
  • Hey! You already answered the other guy's question! Shoo! `;)` – yurisich Feb 25 '12 at 20:36
  • @Droogans, lol, sorry -- I didn't realize it was the same one. – senderle Feb 25 '12 at 20:37
  • @Droogans, but looking at your comments, I think I see what you're getting at, and I think it's more interesting than my answer anyway (which was more educational than efficient). You should post it anyway. – senderle Feb 25 '12 at 20:42
  • Wow...JTLYK, I wrote out a module that *does what their question asked*, but when checking the results, realized that **they posted the incorrect formula**. Oh well, at least I learned a lot. – yurisich Feb 26 '12 at 16:00
0

How about a recursive (and functional!) solution:

def foo(t):
    if len(t) < 2:
        return []
    return [(t[0], t[1])] + foo(t[1:])

Here's another way to solve it, a bit more efficient since it doesn't create temporary slices of t as the above solution:

def foo(t):
    limit = len(t) - 2
    def bar(i):
        if i > limit:
            return []
        return [(t[i], t[i+1])] + bar(i+1)
    return bar(0)
Óscar López
  • 232,561
  • 37
  • 312
  • 386