0
\$\begingroup\$

Q4. Define a function make_counter that returns a counter function, which takes an immutable key and a numerical value argument and returns the sum of all arguments ever passed to counter with that same key.

Below is the solution:

def make_counter():
    """Return a counter function.

    >>> c = make_counter()
    >>> c('a', 3)
    3
    >>> c('a', 5)
    8
    >>> c('b', 7)
    7
    >>> c('a', 9)
    17
    >>> c2 = make_counter()
    >>> c2(1, 2)
    2
    >>> c2(3, 4)
    4
    >>> c2(3, c('b', 6))
    17  
    """
    dict = {}   
    def counter(key, value):
        if key in dict:
            dict[key].append(value)
        else:
            dict[key] = [value]
        lst = dict[key]
        total = 0
        length = len(lst)
        for index in range(length):
            total = total + lst[index]
        return total
    return counter
    """-m doctest gives some weird failure despite all above test case pass"""

Can we improve this solution?

\$\endgroup\$
  • 1
    \$\begingroup\$ Rather than asking three questions in rapid succession, why not ask one, wait for feedback, apply it to the others then ask a follow-up? Also, there's no need to include all of the boiler-plate twice. \$\endgroup\$ – jonrsharpe May 16 '15 at 9:34
  • 3
    \$\begingroup\$ Note that the reason for your doctest failure is trailing whitespace, after the 17 for the final test. It is quite picky about these things! \$\endgroup\$ – jonrsharpe May 16 '15 at 9:38
5
\$\begingroup\$

Choose another name for the dictionary besides dict. Don't ever hide the name of a built-in type.

Then...

d = {}     
def counter(key,value):
    d[key] = d.get(key,0) + value
    return d[key]

You're done. I see no need to build lists of all the passed values.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.