# dict comprehension question.

Terry Reedy tjreedy at udel.edu
Sun Dec 30 00:56:57 CET 2012

```On 12/29/2012 2:48 PM, Quint Rankid wrote:

> Given a list like:
> w = [1, 2, 3, 1, 2, 4, 4, 5, 6, 1]
> I would like to be able to do the following as a dict comprehension.
> a = {}
> for x in w:
>      a[x] = a.get(x,0) + 1
> results in a having the value:
> {1: 3, 2: 2, 3: 1, 4: 2, 5: 1, 6: 1}

Let me paraphrase this: "I have nice, clear, straightforward,
*comprehensible* code that I want to turn into an incomprehensible mess
with a 'comprehension." That is the ironic allure of comprehensions.

Comprehensions do not allow for interactions between the source items.
Mitya and Joel worked around this with solutions that do redundant
calculation and multiply the time order.

Reductions do allow for interactions. Doing everything as a reduction
was the fad before comprehensions came along ;-)

from functools import reduce
w = [1, 2, 3, 1, 2, 4, 4, 5, 6, 1]
def update(dic, n):
"Mutate and return dic (contrary to usual Python policy)"
dic[n] = dic.get(n, 0) + 1
return dic
counts = reduce(update, w, {})
print(counts == {1: 3, 2: 2, 3: 1, 4: 2, 5: 1, 6: 1})

# prints True

The above is how to rewrite your code in a functional language that does
not have statements and explicit iteration. In Python, I would only
bother to wrap the body of the loop in a function if I needed the same
body in multiple places.

Comprehensions are filtered mappings and that both filter and map can be
written as reduction, so reduction included comprehension. It is more
powerful because it can also do sequential interaction. Indeed, I would
say that it should only be used when there is sequential interaction.

--
Terry Jan Reedy

```