Practicando Python: LINQ a Python (2ª parte)

Más ejemplos de ‘conversión’ entre LINQ y Python. Y unas conclusiones a modo de notas mentales:

– GroupBy no agrupa sino que hace rupturas de control (it’s a pain!)
– los grupos resultado de GroupBy, si se requieren para más tarde, deben almacenarse debido a que el iterador generado es siempre el mismo (se resetea en cada ruptura; ver http://docs.python.org/2/library/itertools.html#itertools.groupby)
– Se echan de menos los tipos anónimos
– Sorpenedente que exista el operado + para listas, pero no el operador – (y lo que hay que hacer para simularlo!)

ToArray
This sample uses ToArray to immediately evaluate a sequence into an array.
C#:

double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };
var sortedDoubles =
    from d in doubles
    orderby d descending
    select d;
var doublesArray = sortedDoubles.ToArray(); 

Python:

class Score:
    def __init__ (self, name, score):
        self.Name=name
        self.Score=score
scores=[]
scores.append (Score("Alice",50))
scores.append (Score("Bob",40))
scores.append (Score("Cathy",45))
d= dict([(s.Name, s.Score) for s in scores])

Count – Simple
This sample uses Count to get the number of unique factors of 300.
C#:

int[] factorsOf300 = { 2, 2, 3, 5, 5 };
int uniqueFactors = factorsOf300.Distinct().Count();

Python:

factorsOf300 = [ 2, 2, 3, 5, 5 ]
print len( factorsOf300)

Sum – Simple
This sample uses Sum to get the total of the numbers in an array.
C#:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
double numSum = numbers.Sum(); 

Python:

numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0 ]
print sum(numbers)

Sum – Projection
This sample uses Sum to get the total number of characters of all words in the array.
C#:

string[] words = { "cherry", "apple", "blueberry" };
double totalChars = words.Sum(w => w.Length);

Python:

words = [ "cherry", "apple", "blueberry" ]
print len([len(w) for w in words]);

Min – Projection
This sample uses Min to get the length of the shortest word in an array.
C#:

string[] words = { "cherry", "apple", "blueberry" };
int shortestWord = words.Min(w => w.Length);

Python:

words = [ "cherry", "apple", "blueberry" ,"appla" ]
shortestWord = min([len(word) for word in words])

Max – Elements
This sample uses Max to get the products with the most expensive price in each category.
C#:

    List<Product> products = GetProductList();
    var categories =
        from p in products
        group p by p.Category into g
        let maxPrice = g.Max(p => p.UnitPrice)
        select new { Category = g.Key, MostExpensiveProducts = g.Where(p => p.UnitPrice == maxPrice) }; 

Python:

words = [ "cherry", "apple", "blueberry" ,"appla" ]
minlen= min([len(word) for word in words])
print [w for w in words if len(w)==minlen]

Average – Simple
This sample uses Average to get the average of all numbers in an array.
C#:

string[] words = { "cherry", "apple", "blueberry" };
double averageLength = words.Average(w => w.Length);

Python:

words = [ "cherry", "apple", "blueberry" ,"appla" ]
lens = [len(w) for w in words]
average= float(sum(lens)) / len(words)
print average 

Concat
This sample uses Concat to create one sequence that contains each array’s values, one after the other.
C#:

int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB = { 1, 3, 5, 7, 8 };
var allNumbers = numbersA.Concat(numbersB);

Python:

numbersA = [ 0, 2, 4, 5, 6, 8, 9 ]
numbersB = [ 1, 3, 5, 7, 8 ]
print numbersA  + numbersB

EqualAll
This sample uses EqualAll to see if two sequences match on all elements in the same order.
C#:

var wordsA = new string[] { "cherry", "apple", "blueberry" };
var wordsB = new string[] { "cherry", "apple", "blueberry" };
bool match = wordsA.SequenceEqual(wordsB); 

Python:

wordsA = ["cherry", "apple", "blueberry"]
wordsB = ["cherry", "apple", "blueberry"]
print  wordsA==wordsB;

Deferred Execution
The following sample shows how query execution is deferred until the query is enumerated at a foreach statement.
C#:

// Sequence operators form first-class queries that
// are not executed until you enumerate over them.
int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int i = 0;
var q =
    from n in numbers
    select ++i;
// Note, the local variable 'i' is not incremented
// until each element is evaluated (as a side-effect):
foreach (var v in q)
{
    Console.WriteLine("v = {0}, i = {1}", v, i);
} 

Python:

numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0]
i=1
secuence = (n+i for n in numbers)
i=0
print list(secuence)

Query Reuse
The following sample shows how, because of deferred execution, queries can be used again after data changes and will then operate on the new data.
C#:

// Deferred execution lets us define a query once
// and then reuse it later after data changes.
int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var lowNumbers =
    from n in numbers
    where n <= 3
    select n;
Console.WriteLine("First run numbers <= 3:");
foreach (int n in lowNumbers)
{
    Console.WriteLine(n);
}
for (int i = 0; i < 10; i++)
{
    numbers[i] = -numbers[i];
}
// During this second run, the same query object,
// lowNumbers, will be iterating over the new state
// of numbers[], producing different results:
Console.WriteLine("Second run numbers <= 3:");
foreach (int n in lowNumbers)
{
    Console.WriteLine(n);
}

Python:

## no se puede.... los generadores, una vez exahustos, no se pueden volver a utilizar
## aunque existe un workaround con decorator http://stackoverflow.com/a/1376531/321170

Cross Join
This sample shows how to efficiently join elements of two sequences based on equality between key expressions over the two.
C#:

string[] categories = new string[]{
    "Beverages",
    "Condiments",
    "Vegetables",
    "Dairy Products",
    "Seafood" };
List<Product> products = GetProductList();
var q =
    from c in categories
    join p in products on c equals p.Category
    select new { Category = c, p.ProductName }; 

Python:

categories = [
    "Beverages",
    "Condiments",
    "Vegetables",
    "Dairy Products",
    "Seafood" ]
products = []
q =  [(c, p.ProductName) for c in categories for p in products if c == p.Category]

Group Join
Using a group join you can get all the products that match a given category bundled as a sequence.
C#:

string[] categories = new string[]{
    "Beverages",
    "Condiments",
    "Vegetables",
    "Dairy Products",
    "Seafood" };
List<Product> products = GetProductList();
var q =
    from c in categories
    join p in products on c equals p.Category into ps
    select new { Category = c, Products = ps };

Python:

categories = [
    "Beverages",
    "Condiments",
    "Vegetables",
    "Dairy Products",
    "Seafood" ]
products = [Product("Seafood","percebes"),Product("Seafood","navajas")]
q =  [[c, r] for c in categories for r in [p for p in products if c == p.Category] ]

Left Outer Join
A so-called outer join can be expressed with a group join. A left outer joinis like a cross join, except that all the left hand side elements get included at least once, even if they don’t match any right hand side elements. Note how Vegetablesshows up in the output even though it has no matching products.
C#:

string[] categories = new string[]{
    "Beverages",
    "Condiments",
    "Vegetables",
    "Dairy Products",
    "Seafood" };
List<Product> products = GetProductList();
var q =
    from c in categories
    join p in products on c equals p.Category into ps
    from p in ps.DefaultIfEmpty()
    select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName }; 

Python:

q =  [[c, [p for p in products if c == p.Category]] for c in categories ]
Anuncios
Tagged with: , , ,
Publicado en Programacion

Deixa a túa opinión

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: