'I'm trying to make a function that returns the color of a fruit from dictionary with a try/exception code built within a for loop, but it don't work

'''

Fruits_by_color = {'Yellow':{'Banana', 'Pineapple', 'Passion_Fruit'}, 'Green':{'Avocado', 'Lime', 'Water_melon'}, 'Red':{'Strawberries', 'Apples', 'RaspBerries', 'Pomegranate'}}


def Fruit_color(fruit, dict_):
    for color, fruit in dict_.items():
        color = dict_[color]
        fruit = dict_[color][fruit]
        try:
            print('The color of', fruit, 'is', color)
        except:
            print('There is no such fruit in our data base.')
    
Fruit_color('Banana', Fruits_by_color)

'''

TypeError: unhashable type: 'set'

I've also tried using a list of dictionaries instead of a nested dictionary, but then i've got syntax error:

'''

Fruits_by_color = ['Yellow':{'Banana', 'Pineapple', 'Passion_Fruit'}, 'Green':{'Avocado', 'Lime', 'Water_melon'}, 'Red':{'Strawberries', 'Apples', 'RaspBerries', 'Pomegranate'}]


def Fruit_color(fruit, list_):
    for color, fruit in list_():
        color = list_[color]
        fruit = list_[color][fruit]
        try:
            print('The color of', fruit, 'is', color)
        except:
            print('There is no such fruit in our data base.')
    
Fruit_color('Banana', Fruits_by_color)

'''

I then get a SyntaxError



Solution 1:[1]

About the error message

Despite that {'Banana', 'Pineapple', 'Passion_Fruit'} is written with brackets, this is not a dictionary but a set (leading to the error).

color = dict_[color] assigns the content of the color key to the color variable. In your example, color will have the value {'Banana', 'Pineapple', 'Passion_Fruit'}. At the next line, when you try to get the fruit with fruit = dict_[color][fruit], Python raises an error because you it tries to run dict_[{'Banana', 'Pineapple', 'Passion_Fruit'}] and set are not hashable.

Printing the color of a fruit

Same data structure

With your current data, you could do something like this:

fruits_by_color = {
    'Yellow': {'Banana', 'Pineapple', 'Passion_Fruit'},
    'Green': {'Avocado', 'Lime', 'Water_melon'},
    'Red': {'Strawberries', 'Apples', 'RaspBerries', 'Pomegranate'},
}


def fruit_color(fruit, fruits_and_colors):
    found = False
    for color, colored_fruits in fruits_and_colors.items():
        if fruit in colored_fruits:
            found = True
            print('The color of', fruit, 'is', color)
    if not found:
        print('There is no such fruit in our data base.')


fruit_color('Banana', fruits_by_color)
fruit_color('potato', fruits_by_color)

Another data structure

You can also change the datastructure and do something like this:

fruits_by_color = {
    'Yellow': {'Banana', 'Pineapple', 'Passion_Fruit'},
    'Green': {'Avocado', 'Lime', 'Water_melon'},
    'Red': {'Strawberries', 'Apples', 'RaspBerries', 'Pomegranate'},
}


def build_fruit_and_colors():
    fruit_and_colors = {}
    for color, colored_fruits in fruits_by_color.items():
        to_add = {one_fruit: color for one_fruit in colored_fruits}
        fruit_and_colors.update(to_add)
    return fruit_and_colors


def fruit_color(fruit, fruits_and_colors):
    try:
        print('The color of', fruit, 'is', fruits_and_colors[fruit])
    except KeyError:
        print('There is no such fruit in our data base.')

fruit_and_colors = build_fruit_and_colors()

fruit_color('Banana', fruit_and_colors)
fruit_color('banana', fruit_and_colors) # won't be found
fruit_color('potato', fruit_and_colors)

Warning: the previous code doesn't manage:

  1. if a fruit has two colors (each key is unique in a dictionary)
  2. a fruit given in lower case won't be found (the second call with banana).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ndclt