Question

def tointervals(tlist):
      count=0
      for i in tlist:
        if count == 0:
          count = count + 1
          yield 0
        else:
          count = count + 1
          yield i - tlist[count -2]

I test it like so:

In [272]: list(tointervals([1,2,3,4,10]))
Out[272]: [0, 1, 1, 1, 6]

Great, that's exactly what I was looking for

But I want to do it in a more functional way (I'm mostly using Scala)

I'm terminally confused about this, mainly due to unfamiliarity with Python. The closest I've gotten before giving up in terminal confusion is this.

In [292]: reduce(lambda x,y: (x[0] + [y - x[0][x[1]] ],x[1]+1), [1,2,3,4,10], ([0],0))
Out[292]: ([0, 1, 1, 2, 2, 8], 5)

Which is obviously wrong, but that's the direction I was trying... Am I being foolish, trying to use reduce, or can I just not code for toffee? Be gentle, please.

Was it helpful?

Solution

A list comprehension will be more pythonic:

>>> l = [1, 2, 3, 4, 10]
>>> [y-x for x, y in zip(l, l[1:])]
[1, 1, 1, 6]

OTHER TIPS

This is the Pythonic way, if I understand correctly what your intention is:

def tointervals(l):
    return [0] + [l[i] - l[i-1] for i in xrange(1, len(l))]

or

def tointervals(l):
    return (y-x for x,y in itertools.izip([l[0]] + l[:-1], l))

Functional programming is not considered a goal per se in the Python community and language support for it is limited -- "practicality beats purity".

I'd rather go with one of more pythonic solutions from this thread, but if you want to see the reduce-based solution just for fun, it would be something like that:

reduce(lambda x,y: (x[0] + [y-x[1]], y), [1,2,3,4,10], ([], 0))

Please do not try that in real-life code because your colleagues will curse you.

Building on larsmans' answer, you could also make a generator like you do in your procedural code:

def tointervals(xs):
    return itertools.chain((0,), (xs[i] - xs[i-1] for i in range(1, len(xs))))

Note: use xrange with python2.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top