Transform cycle in function of higher order

0

Good afternoon, I have this function containing a cycle:

def ciclo(x,y):
    lista = []
    for i in x:
        if i[0]==y:
            lista.append(i[3])
    return sorted(lista)

And I wanted to turn it into a line of code, using the python map function.

I already have this: sorted(map(lambda i: i[3], x))

But this only contains the cycle, if i[0]==y I do not know how to do it to get it inside the map function.

    
asked by anonymous 19.04.2016 / 16:59

2 answers

0

You could use conditional expressions (rather than an exotic ternary) and return None case [0] is different from y and then apply filter to remove Nones:

def higherOrderCycle(x, y):
    return sorted(
        filter(
            lambda v: v != None, 
            map(lambda v: v[3] if v[0] == y else None, x)
        )
    )

Note that if you are expecting None in v[3] you would need to adapt this function. Also though the implementation with higher order functions is very beautiful and within the functional paradigm it is much more obscure than the one you posted, so outside learning I see no reason to use it in place of the other.     

19.04.2016 / 17:22
3

In Python this is a line:

sorted(i[3] for i in x if i[0] == y)

Forget the use of "map" in general it is more complicated than the "generator expressions" and "list comprehensions" that we have embedded in the language - these chic names are for use of the "for" command in an inline expression as above - and allow, without the use of the "map", "filter", or the keyword "lambda" the mapping and filtering of any data set:

Basically, you write "<expressão> for item in <iterador> if <expressão-de-filtro>" wherever the language expects an iterator - it will give you all items in the iterator, and for each it will process < Expressão> if expressão-de-filtro is true. That is, the initial expression plays the role of the "map", and the expression after "if" plays the role of the "filter".

If you want the end result in a list, put this syntax in brackets. ( [<expressão> for item in <iterador> if <expressão-de-filtro>] ) - in case, as you want the ordered results, instead, I passed the iterator for a call to sorted that returns a list object already ordered.

The expression I gave above would be the equivalent of:

map((lambda i: i[3]), filter((lambda i: i[0] == y), x) )   

(that is, the iterator returned by the call to filter is the sequence parameter for calling map - is much harder to read)

(Note also that it is better to protect lambdas with parentheses to avoid ambiguity for human readers if "," indicates the end of the lambda, or indicates that the lambda will return a tuple instead of a single result)

    
22.04.2016 / 22:32