Correct use of lambda with filter()

Asked

Viewed 76 times

2

Here is a practical example of a script that simulates a seller’s sales days and extracts only the days when the seller hit the day’s quota. The list represents the month (I entered only 3 days for practical example) and the dictionaries the days themselves, with sales values and KPI’s. In this script I used the simplest solution with a loop For, see:

vendas = [{"Dia": '1', "Cota": 3200, "Venda": 2500, "PA": 2, "VM": 1452},
          {"Dia": '2', "Cota": 3200, "Venda": 1803, "PA": 2.4, "VM": 1452},
          {"Dia": '3', "Cota": 5000, "Venda": 8500, "PA": 1.82, "VM": 1385}]
# Objetivo é gerar uma lista com os dias em que o vendedor bateu a cota
print('O vendedor bateu cota nos dias...', end=' ')
for c, dia in enumerate(vendas):
  if dia["Venda"] >= dia["Cota"]:
    print(dia["Dia"], end= ', ')

Easy right?

Now, what if I want to wear one lambda with filter to extract exactly the same result? Intuitively, this was the code I wrote and is not compiling:

# Com filter imprimindo a lista inteira de uma vez
print('O vendedor bateu cota nos dias...', end=' ')
print(list(filter(lambda x['Dia']: x['Venda'] >= x['Cota'], vendas)))

Can you help me build this solution with this feature? Is it possible? It would be nice to build the solution with List Comprehension tb because I could not. Thank you!

1 answer

5

filter is a function used to return items from your list that meet the condition, and nothing else. If your goal is to create a list containing only the days of these items that meet the condition, only the function filter will not be enough, you will also need something like map, that serves to transform your list.

Now why your code is error is because the syntax is incorrect. lambda declares an anonymous function, as follows lambda [argumentos]: [retorno], note that where you should be declaring your arguments you are declaring x['Dia'], That would be the equivalent of:

def minha_lambda(x['Dia']):
    return x['Venda'] >= x['Cota']

Is this function valid? Obviously not, the right one would be:

def minha_lambda(x):
    return x['Venda'] >= x['Cota']

Therefore, its stated function with lambda should be lambda x: x['Venda'] >= x['Cota']

In conjunction with map, you would have:

vendas_filtradas = filter(lambda x: x['Venda'] >= x['Cota'], vendas)
dias = map(lambda x: x['Dia'], vendas_filtradas)
print(list(dias))

With list comprehension this approach becomes more direct, because you can filter and transform your list in a single step.

dias = [x['Dia']     for x in vendas     if x['Venda'] >= x['Cota']]
#       ^ retorno    ^ laço de repetição ^ condição do filtro
print(dias)

I believe that’s what you were trying to do in yours filter.

  • Perfect! Another question: why do we have to flag with list() before printing the result? Map does not automatically generate a list object?

  • 1

    @dev.Uri, no, the function map returns an instance of map. You can iterate on instances of map with a bow for, but map is not a list; cannot add more items to a map, and if you print it directly on the console will appear only map object at [endereço de memória]

  • nice @user140828. So to visualize the instance I should assign an object that is printable (roughly speaking), is that it? In the case of this example I could for example play inside a tuple, because I won’t add or change that instance. PS. I can only iterate under the instance of this map() if I sort it, right?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.