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

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to