Linq to Python
Duncan Booth
duncan.booth at invalid.invalid
Wed Sep 24 16:59:12 EDT 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