Linq to Python

Duncan Booth duncan.booth at invalid.invalid
Wed Sep 24 22:59:12 CEST 2008


r0g <aioe.org at technicalbloke.com> wrote:

> OK so maybe I'm being naive here but it looks to me like this new
> paradigm's big idea is to use a python + SQL type syntax to access data
> in random objects. Big whoop. It's not that difficult to write a
> generators that wraps XML files and databases is it?
> 
> What am I missing here?

Simple LINQ expressions like the one you gave map easily to Python list 
comprehensions. What Microsoft have done though is provide a consistent 
implementation which allows you to write complex SQL like expressions which 
will work identically on databases or most other sequence types.

Here's another LINQ example:

   List<Customer> customers = GetCustomerList();
 
   var customerOrderGroups = 
       from c in customers
       select
           new {c.CompanyName, 
                YearGroups =
                from o in c.Orders
                  group o by o.OrderDate.Year into yg
                  select
                  new {Year = yg.Key,
                       MonthGroups = 
                         from o in yg
                         group o by o.OrderDate.Month into mg
                         select new { Month = mg.Key, Orders = mg }
                      }
                };
                           
   ObjectDumper.Write(customerOrderGroups, 3);

I'm not overly keen on SQL syntax: I think this sort of complex expression 
is hard to read. LINQ has a pretty straightforward conversion to method 
calls, and for me this consistent set of methods is the important thing 
rather than the SQL syntax. e.g. 'group by' maps directly to a call to a 
method GroupBy(), so another of Microsoft's LINQ examples is:

public void Linq45() {
            string[] anagrams = {"from ", " salt", " earn ", " last ",
                                 " near ", " form "};
 
            var orderGroups = anagrams.GroupBy(
                        w => w.Trim(), 
                        a => a.ToUpper(),
                        new AnagramEqualityComparer()
                        );
                           
            ObjectDumper.Write(orderGroups, 1);
        }
 
public class AnagramEqualityComparer : IEqualityComparer<string>
        {
            public bool Equals(string x, string y) {
                return getCanonicalString(x) == getCanonicalString(y);
            }
 
            public int GetHashCode(string obj) {
                return getCanonicalString(obj).GetHashCode();
            }
            
            private string getCanonicalString(string word) {
                char[] wordChars = word.ToCharArray();
                Array.Sort<char>(wordChars);
                return new string(wordChars);
            }
        }

Python still wins hands down on this example both in verbosity and 
readability:

>>> anagrams = ["from ", " salt", " earn ", " last ",
                                 " near ", " form "]
>>> from itertools import groupby
>>> def AnagramKey(w):
	return sorted(w.strip().upper())

>>> for k,words in groupby(sorted(anagrams, key=AnagramKey), 
key=AnagramKey):
	for w in words:
		print w.strip().upper()
	print "..."

	
EARN
NEAR
...
SALT
LAST
...
FROM
FORM
...

I haven't yet had occasion to use LINQ in anger yet, so I have no idea 
whether its an idea to love or to hate. I do think it is good that C# has 
effectively sprouted list comprehensions (not to mention anonymous types 
and type inferencing) and I expect there may be some aspects worth looking 
at for Python but I think they are more likely to lead to itertools 
functions than extensions to syntax.



More information about the Python-list mailing list