Home > Mobile >  Simpler way of creating a new dictionary with the values of another dictionary as keys, and the numb
Simpler way of creating a new dictionary with the values of another dictionary as keys, and the numb

Time:11-05

Instead of explaining further, I will first provide some context with my code which works but seems very inefficient:

def get_quantities(table_to_foods: Dict[str, List[str]]) -> Dict[str, int]:
    """The table_to_foods dict has table names as keys (e.g., 't1', 't2', and
    so on) and each value is a list of foods ordered for that table.

    Return a dictionary where each key is a food from table_to_foods and each
    value is the quantity of that food that was ordered.
    
    >>> get_quantities({'t1': ['Vegetarian stew', 'Poutine', 'Vegetarian stew'],
    't3': ['Steak pie', 'Poutine', 'Vegetarian stew'], 't4': ['Steak pie', 'Steak pie']})

    {'Vegetarian stew': 3, 'Poutine': 2, 'Steak pie': 3}    

    >>> get_quantities({'t1': ['pie'],
    't2': ['orange pie'], 't3': ['pie']})

    {'pie': 2, 'orange pie': 1} 
    """

    food_to_quantity = {}
    
    # Accumulate the food information here.

    # Creating a dictionary with the new keys as values from the other
    for j in table_to_foods.values():
      for a in j:
        food_to_quantity[a] = 0
    
    # Increment based on number of occurrences
    for j in table_to_foods.values():
      for a in j:
        food_to_quantity[a]  = 1

    return food_to_quantity

There must be a much simpler way of creating a new dictionary with the values of table_to_foods as keys, and the number of occurrences of any food value as the value.

CodePudding user response:

Here is how I would do.

table_to_foods = {'t1': ['Vegetarian stew', 'Poutine', 'Vegetarian stew'],
't3': ['Steak pie', 'Poutine', 'Vegetarian stew'], 't4': ['Steak pie', 'Steak pie']}

food_to_quantity = {}
for foods in table_to_foods.values():
    for food in foods:
        if(food not in food_to_quantity):
            food_to_quantity[food]=1
        else:
            food_to_quantity[food] =1

print(food_to_quantity)

output: {'Vegetarian stew': 3, 'Poutine': 2, 'Steak pie': 3}

CodePudding user response:

You can use collections.Counter and itertools.chain:

from collections import Counter
from itertools import chain

def get_quantities(d):
    return dict(Counter(chain.from_iterable(d.values())))

d1 = {'t1': ['Vegetarian stew', 'Poutine', 'Vegetarian stew'], 't3': ['Steak pie', 'Poutine', 'Vegetarian stew'], 't4': ['Steak pie', 'Steak pie']}
d2 = {'t1': ['pie'], 't2': ['orange pie'], 't3': ['pie']}

print(get_quantities(d1)) # {'Vegetarian stew': 3, 'Poutine': 2, 'Steak pie': 3}
print(get_quantities(d2)) # {'pie': 2, 'orange pie': 1}

(dict in the return line is redundant in most use cases.)

If you are not a fan of using additional modules, you can do instead:

def get_quantities(d):
    output = {}
    for lst in d.values():
        for x in lst:
            output[x] = output.get(x, 0)   1
    return output
  • Related