views:

1029

answers:

3

Is it possible to use the LINQ types and extension methods in IronPython?

If so how? And also is there often more pythonic to do the same thing?

+4  A: 

There's no direct LINQ support; the special LINQ syntax would require a rewrite of parts of Python, so that's not available right now. But nothing stops you from calling the static methods directly:

Queryable.Select(Queryable.Where(numbers, biggerThanThree), myFunc)

This is obviously a suboptimal solution compared to what you want. But alas, I'm afraid that's where things stand for now. You might find this blog post to be of help:

http://ironpython-urls.blogspot.com/2009/01/devhawk-ironpython-and-linq-to-xml.html

John Feminella
That's better than nothing, Thanks.
tarn
+6  A: 

Some of the things you'd do with LINQ can be done with list comprehensions:

[myFunc(i) for i in numbers if i > 3]

Or you can use map, reduce, and filter:

map(myFunc, filter(lambda x: x > 3, numbers))

But list comprehensions are much more "Pythonic" than using the functional programming constructs. For reducing things, consider using "".join or sum. And you can check the truth value of entire iterables by using any and all

Just remember these translations:

Select -> map
Where -> filter
Aggregate -> reduce

And you'll be well on your way!

Patrick
+1  A: 

I described a C# wrapper class around the LINQ extension methods to achieve a syntax similar to C#'s 'chained extension method' syntax in IronPython.

The idea is to have a kind of decorator class around IEnumerable that simply calls the extension methods. Probably this wrapper class can be written just as well in IronPython, but I'm not as fluent in python yet :-)

public class ToLinq<T> : IEnumerable<T>
{
    private readonly IEnumerable<T> _wrapped;

    public ToLinq(IEnumerable<T> wrapped)
    {
       _wrapped = wrapped;
    }

    public ToLinq<T> Where(Func<T, bool> predicate)
    {
        return new ToLinq<T>(_wrapped.Where(predicate));
    }


    // ... similar methods for other operators like Select, Count, Any, ...

}

This allows for a syntax similar to this:

johns = ToLinq[Customer](customers)\
          .Where(lambda c: c.Name.StartsWith("John"))\
          .Select(lambda c: c.Name)

Disclaimer: this is something I tried as a learning excercise, I haven't used this in a real-world project.

jeroenh