Vroomfondel
Vroomfondel

Reputation: 2898

Currying iterators in Python

In the following snippet I try to return a function which is returning a generator (weren't they once called iterators BTW?) with the step argument curried.

import math
import numpy

def aequi_ang_step(step):
    def local_it(start, d_alpha, step):
        for alpha in numpy.arange(start, start+d_alpha,(d_alpha < 0) and -step or step):
            if (alpha < 2*math.pi): yield alpha
            else: yield alpha-2*math.pi
    return lambda start, d_alpha: local_it(start, d_alpha, step)

The thing works but as I am returning from a long abstinence back to Python my question is if this is an ok and pythonic way to curry iterators in Python.

Upvotes: 0

Views: 220

Answers (1)

Kyle Parsons
Kyle Parsons

Reputation: 1525

This is not exactly how I would approach the problem here. In particular, returning a lambda is discouraged. Consider instead

import math
import numpy

def aequi_ang_step(step):
    def local_it(start, d_alpha):
        for alpha in numpy.arange(start, start+d_alpha,(d_alpha < 0) and -step or step):
            if (alpha < 2*math.pi): yield alpha
            else: yield alpha-2*math.pi
    return local_it

Now what you return is a closure which includes a definition for step.

I think a more pythonic approach in general for currying, is functools.partial

from functools import partial
import math
import numpy

step = 0.1

def aequi_ang(start, d_alpha, step):
    for alpha in numpy.arange(start, start+d_alpha,(d_alpha < 0) and -step or step):
        if (alpha < 2*math.pi): yield alpha
        else: yield alpha-2*math.pi

aequi_ang_step = partial(aequi_ang, step=step)

Upvotes: 2

Related Questions