Sum of all arguments ever passed to counter 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.

    &gt;&gt;&gt; c = make_counter()
    &gt;&gt;&gt; c('a', 3)
    3
    &gt;&gt;&gt; c('a', 5)
    8
    &gt;&gt;&gt; c('b', 7)
    7
    &gt;&gt;&gt; c('a', 9)
    17
    &gt;&gt;&gt; c2 = make_counter()
    &gt;&gt;&gt; c2(1, 2)
    2
    &gt;&gt;&gt; c2(3, 4)
    4
    &gt;&gt;&gt; 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?
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.