Search code examples
pythonfunctional-programmingiteratormethod-chainingfluent-interface

Python equivalents to LINQ


In C#, with LINQ, if I have en enumeration enumerable, I can do:

// a: Does the enumerable contain an item that satisfies the lambda?
bool contains = enumerable.Any(lambda);

// b: How many items satisfy the lambda?
int count = enumerable.Count(lambda);

// c: Return an enumerable that contains only distinct elements according to my custom comparer
var distinct = enumerable.Distinct(comparer);

// d: Return the first element that satisfies the lambda, or throws an exception if none
var element = enumerable.First(lambda);

// e: Returns an enumerable containing all the elements except those
// that are also in 'other', equality being defined by my comparer
var except = enumerable.Except(other, comparer);

I hear that Python has a more concise syntax than C# (and is therefore more productive), so how do I achieve the same with an iterable in Python, with the same amount of code, or less?

Note: I don't want to materialize the iterable into a list if I don't have to (Any, Count, First).


Solution

  • The following Python lines should be equivalent to what you have (assuming func, or lambda in your code, returns a Boolean):

    # Any
    contains = any(func(x) for x in enumerable)
    
    # Count
    count = sum(func(x) for x in enumerable)
    
    # Distinct: since we are using a custom comparer here, we need a loop to keep 
    # track of what has been seen already
    distinct = []
    seen = set()
    for x in enumerable:
        comp = comparer(x)
        if not comp in seen:
            seen.add(comp)
            distinct.append(x)
    
    # First
    element = next(iter(enumerable))
    
    # Except
    except_ = [x for x in enumerable if not comparer(x) in other]
    

    References:

    Note that I renamed lambda to func since lambda is a keyword in Python, and I renamed except to except_ for the same reason.

    Note that you could also use map() instead of the comprehensions/generators, but it is generally considered less readable.