One of the most beloved C# 3.0 features is Linq. Linq brings great power to C#, it allows you to easily write structured queries over collections or remote data sources. Now with C# is possible to make queries as easy as with other languages like Python. I decided to compare the way you make queries with C# and with Python. I found a great page showing 101 Linq examples, I decided to write Python versions of this examples. Which version do you like more?

C# version:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var lowNums = from n in numbers where n < 5 select n;

Python version:

numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0] low_nums = (nforninnumbersifn < 5)

C# version:

string[] digits = {"zero","one","two","three","four","five","six","seven","eight","nine"}; var shortDigits = digits.Where((digit, index) => digit.Length < index);

Python version:

digits = ['zero','one','two','three','four','five','six','seven','eight','nine'] short_digits = (digitforindex, digitinenumerate(digits)iflen(digit) < index)

C# version:

var numsPlusOne = from n in numbers select n + 1;

Python version:

nums_plus_one = (n + 1forninnumbers)

C# version:

string[] words = {"aPPLE","BlUeBeRrY","cHeRry"}; var upperLowerWords = from w in words select new {Upper = w.ToUpper(), Lower = w.ToLower()};

Python version:

The exact Python version would be something like:

words = ['aPPLE','BlUeBeRrY','cHeRry'] upper_lower_words = ( type('', (), {'upper': w.upper(),'lower': w.upper() })forwinwords)

But I feel more Pythonic this:

upper_lower_words = ( (w.lower(), w.upper())forwinwords)

Or even this:

upper_lower_words = ( {'upper': w.upper(),'lower': w.upper() }forwinwords)

C# version:

int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };int[] numbersB = { 1, 3, 5, 7, 8 }; var pairs = from a in numbersA, b in numbersB where a < b select new {a, b};

Python version:

numbersA = [0, 2, 4, 5, 6, 8, 9] numbersB = [1, 3, 5, 7, 8 ] pairs = ( (a, b)forainnumbersAforbinnumbersBifa < b)

C# version:

var orders = from c in customers, o in c.Orders, total = o.Total where total >= 2000.0M select new {c.CustomerID, o.OrderID, total};

Python version:

I couldn’t find how to make the assignment in Python, so the version is:

orders = ( {'customer_id': c.customer_id,'order_id': o.order_id,'total': o.total }forcincustomersforoinc.ordersifo.total > 2000)

C# version:

var orders = from c in customers where c.Region =="WA"from o in c.Orders where o.OrderDate >= cutoffDate select new {c.CustomerID, o.OrderID};

Python version:

orders = ( (c.customer_id, o.order_id)forcincustomersifc.region =='WA'foroinc.ordersifo.date >= cutoff_date)

C# version:

var first3Numbers = numbers.Take(3);

Python version:

if we are working with something like a list, we could do:

first_3_numbers = numbers[:3]

but, if we are working with iterators, we must do:

first_3_numbers = itertools.islice(numbers, None, 3)

C# version:

var allButFirst4Numbers = numbers.Skip(4);

Python version:

all_but_fist_4_numbers = numbers[4:]# list versionall_but_fist_4_numbers = itertools.islice(numbers, 4, None)# iterator version

C# version:

var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);

Python version:

fist_numbers_less_that_6 = itertools.takewhile(lambdax: x < 6, numbers)

C# version:

var allButFirst3Numbers = numbers.SkipWhile(n => n % 3 != 0);

Python version:

all_but_first_3_numbers = itertools.dropwhile(lambdax: x % 3 != 0, numbers)

C# version:

numbers.First() numbers.Last()

Python version:

numbers[0]# first for a listnumbers[-1]# last for a listnumbers.next()# first for iteratorlist(numbers)[0]# first for iteratorlist(numbers)[-1]# last for iterator

C# version:

intevenNum = numbers.First((num, index) => (num % 2 == 0) && (index % 2 == 0));

Python version:

even_num = [nfori, ninenumerate(numbers)ifn%2 == 0andi%2 == 0][0]

or:

even_num = (nfori, ninenumerate(numbers)ifn%2 == 0andi%2 == 0).next()

to be continued…

That’s way the bestest answer so far!