2

basically I'm trying to calculate the sums of resources required in a recursive array with associate patterns...

here's a simplified example of what I'm trying to achieve:

resources = { resource: resources.get( resource, 0 )+1 for resource in generator }

now of course the above code doesn't work because resources is unresolvable, but I want to access the dict as it's being created... is there some way I can do this??

Tcll
  • 7,140
  • 1
  • 20
  • 23
  • Are you just looking for a [`Counter`](https://docs.python.org/3/library/collections.html#collections.Counter)? – glibdud Nov 21 '17 at 20:05
  • 1
    Related, for list comprehension: https://stackoverflow.com/a/5056466/3001761. Until the dictionary is completely created, it's not accessible. – jonrsharpe Nov 21 '17 at 20:07
  • thanks, that answers my question telling me it's not possible, but why was I downvoted?? – Tcll Nov 21 '17 at 20:13

1 Answers1

2

This is an old question. The answer is: you can't (or if you can, you shouldn't).

But there is a flaw in your idea (that's why I write this answer): you are using the wrong tool. I'm not talking of collections.Counter, but of functional tools. List comprehensions is a:

a syntactic construct available in some programming languages for creating a list based on existing lists. (Wikipedia)

Here, you want to create a list based on an existing list and on the current state of your list. This could not be, by definition, a list comprehension by the book.

But there is another functional construction that is perfectly suitable for this case: the fold. A fold:

through use of a given combining operation, recombine the results of recursively processing its constituent parts, building up a return value (Wikipedia)

In Python, you have to use the reduce function of the functools module:

>>> generator = (i%7 for i in range(20))
>>> import functools
>>> functools.reduce(lambda resources, resource: {**resources, resource: resources.get(resource, 0) + 1}, generator, {})
{0: 3, 1: 3, 2: 3, 3: 3, 4: 3, 5: 3, 6: 2}

The combining function takes the current dictionary and replaces the value associated to resource by the previous value + 1.

Of course, a regular loop would be okay too.

jferard
  • 7,835
  • 2
  • 22
  • 35
  • considering I already backtracked and did things differently, I'm marking this as an accepted answer for the `functools.reduce` solution, thank you :) – Tcll Jul 25 '19 at 23:12
  • 1
    @Tcll You are welcome. I didn't expect any feedback on this answer. Thanks! – jferard Jul 26 '19 at 04:28