Search code examples
python-3.6defaultdict

Append to defaultdict(list) based upon items in an iterable


I have a program that is supposed to apply a function to an iterable and return a dict(list) in which the keys are the values from the function and the values in the list are the items that produced the value from the function.

Code:

from collections import defaultdict


numbers = [1, 4, 5, 6, 8, 19, 34, 55]
d = defaultdict(list)


def modn(n):
    return n % 3


def group_by_value(it, func):
    result = map(func, it)

    for i in result:
        for j in it:
            d[i].append(j)

    return d


print(group_by_value(numbers, modn))

I am getting: {1: [1, 4, 5, 6, 8, 19, 34, 55, 1, 4, 5, 6, 8, 19, 34, 55, 1, 4, 5, 6, 8, 19, 34, 55, 1, 4, 5, 6, 8, 19, 34, 55, 1, 4, 5, 6, 8, 19, 34, 55], 2: [1, 4, 5, 6, 8, 19, 34, 55, 1, 4, 5, 6, 8, 19, 34, 55], 0: [1, 4, 5, 6, 8, 19, 34, 55]}

I should get:

{0: [6], 1: [1, 4, 19, 34, 55], 2: [5, 8]}

I understand why I am getting the wrong result. However, I keep wanting to run the modn() function twice: once to get the result, and once to do a comparison to see if the item in numbers is already there. I can't help but think I should not have to run that function twice, but I am stuck.

I should be able to apply the function to each item in the iterable, get the return value, then populate the list with the items from the iterable that produced the value, without running the function twice.


Solution

  • Logically breaking down the steps:

    1.Get the resulting values from the function

    2.Build a dictionary where the keys are the resulting values and the values are []

    3.For each value in 'it', append it to the key in dictionary that has its resultant value

    def group_by_value(it, func):
        result = list(map(func, it))
        d = {i:[] for i in result}
        for i in range(len(it)):
            d[result[i]].append(it[i])
    
        return d
    
    group_by_value(numbers, modn)
    >>>{1: [1, 4, 19, 34, 55], 2: [5, 8], 0: [6]}