I was answering a question, during my testing process to find the solution my idea was to do a dictionary compression, the problem was to go through a list with dictionaries and add the values.
Ready
clientes = [
{
"abonado": "amazon_prime",
"valor_a_pagar": 30000
},
{
"abonado": "netflix",
"valor_a_pagar": 35000
},
{
"abonado": "amazon_prime",
"valor_a_pagar": 22000
},
{
"abonado": "amazon_prime",
"valor_a_pagar": 28000
},
{
"abonado": "netflix",
"valor_a_pagar": 35000
},
{
"abonado": "amazon_prime",
"valor_a_pagar": 23000
},
{
"abonado": "netflix",
"valor_a_pagar": 18000
}
]
The result should be a dictionary with the sum of the total to pay in each case, something like this (ignore the key total
):
{
'total': 191000,
'amazon_prime': 103000,
'netflix': 88000
}
Well, for this one of my solutions was the following:
{clientes[i]["abonado"]:clientes[i]["valor_a_pagar"] for i in range(len(clientes)) }
However this returns only the last value.
{
'amazon_prime': 23000,
'netflix': 18000
}
My question is, how can I add the values to my dictionary using dictionary compression?
The purpose of list comprehension is to create a new list, not to serve as a reducer function. Before the existence of list comprehension, higher order functions such as map, reduce, filter, etc. were used. Currently, list comprehension manages to cover a large part of the use cases of map and/or filter, however reduce is still ideal for those cases where it is necessary to reduce a list of objects to an object, in this case an object with the accumulated of the amounts per platform (netflix, amazon...).
The full program would be something like this...
Basically the reduce function receives 3 arguments:
Registro
and as the second argument, the current object of the list being iterated over. This function should return the updated accumulating object that will be passed the next time this function is called but now with the next element inside the iterable.Basically what reduce does is take the cumulative value defined in the third argument
Registro()
, then call the functionregistrar
with the cumulative value as the first argument and the first element of the iterable as the second argument, finally the returned result becomes the new cumulative and repeats the process but now taking into account the second value of iterable, the process is repeated until the end of going through the iterable.You can't, and you shouldn't. By definition, an understanding is:
The emphasis is mine. My translation:
And what you want is to create, in this case, a dictionary, based on another dictionary and the current state of the new dictionary .
This, conceptually, is no longer an understanding, it is something else.
Instead, there is another construction you can use : fold
To fold in python, you can use
reduce
thefunctools
. For example, you can find the exact result you are looking for, in a format similar to the one you propose, with the expression:With your data, produce the following output:
Since the original dictionary is iterable, you can simplify the expression to:
Which produces the same result.
Actually you can, which I'm not really sure if it's a good method. Since you already use list comprehension and dictionary handling in your question, I think it doesn't deserve further explanation:
the aforementioned list:
there is not much science, a list compression within dictionary comprehension
Bring back:
Seeing the other answers I tell you: yes it can, what I repeat because I haven't seen it is yes it should, although if it works I don't see why not.