Is there a way to get the key from a list embedded in a dictionary

Viewed 59

I am trying to write a function that, given a dictionary of restaurants, allows you to randomly pick a restaurant based on your choice of one of the values. For example, if you say you want a bakery then it will only give you bakeries.

I have only worked on the code for choosing the type of restaurant so far, and I am struggling with how to generate a random list. So I am checking for a value and, if it has it, would want to add the key to a list. Does anyone have any suggestions on how to do this?

import random 
Restaurants ={

"Eureka": ["American", "$$", "Lunch", "Dinner"],
"Le_Pain": ["Bakery", "$$", "Breakfast", "Lunch", "Dinner"],
"Creme_Bakery": ["Bakery", "$", "Snack"]

}

list=[]

def simple_chooser():
    print('Would you like to lock a category or randomize? (randomize, type, price, or meal)')
    start= input() 
    if start=="randomize":
        return #completely random
    elif start=="type":
        print("American, Bakery, Pie, Ice_Cream, Bagels, Asian, Chocolate, Italian, Pizza, Thai, Mexican, Japanese, Acai, Mediterranean, or Boba/Coffee?")
        type=input()
        for lst in Restaurants.values():
           for x in lst:
                if x==type:
                    list.append(x)
                return(random.choice(list)) 
3 Answers

In your loop, you don't have the restaurant name, as you iterate on the values, you would have need something like

for name, props in Restaurants.items():
    if props[0] == type:
        list.append(name)
return (random.choice(list)) # wait for the whole list to be constructed

With a better naming (don't use type and list that are builtin methods)

def simple_chooser():
    start = input('Would you like to lock a category or randomize? (randomize, type, price, or meal)')
    if start == "randomize":
        return  # completely random
    elif start == "type":
        restaurant_type = input("American, Bakery, Pie, Ice_Cream, Bagels, Asian, Chocolate, Italian, "
                                "Pizza, Thai, Mexican, Japanese, Acai, Mediterranean, or Boba/Coffee?")
        matching_names = [name for name, props in Restaurants.items() if props[0] == restaurant_type]
        return random.choice(matching_names)

To return completely random restaurant suggestions you need to create a list of all the types first and then you can choose one and return the names of the restaurants.

import random 
Restaurants ={

"Eureka": ["American", "$$", "Lunch", "Dinner"],
"Le_Pain": ["Bakery", "$$", "Breakfast", "Lunch", "Dinner"],
"Creme_Bakery": ["Bakery", "$", "Snack"]

}

types = ['American', 'Bakery', 'Pie', 'Ice_Cream', 'Bagels', 'Asian', 'Chocolate', 'Italian', 
'Pizza', 'Thai', 'Mexican', 'Japanese', 'Acai', 'Mediterranean','Boba/Coffee']

    def simple_chooser():
        l=[]
        print('Would you like to lock a category or randomize? (randomize, type, price, or meal)')
        start= input() 
        if start=="randomize":
            type_random = random.choice(types)
            for k,v in Restaurants.items():
                if v[0] == type_random:
                    l.append(k)
    
        elif start=="type":
            print("American, Bakery, Pie, Ice_Cream, Bagels, Asian, Chocolate, Italian, Pizza, Thai, Mexican, Japanese, Acai, Mediterranean, or Boba/Coffee?")
            type_chosen=input()
            for k,v in Restaurants.items():
                if v[0] == type_chosen:
                    l.append(k)
    
        return(random.choice(l))

Also, you don't need to return in if-else statements. Once you have your list of Restaurants you can randomly choose a restaurant and return it.

You make processing difficult because of the design of your data structures.

Here's an idea which should be easily adapted to future needs.

import random
from operator import contains, eq

Restaurants = [
    {'name': 'Eureka', 'type': 'American', 'price': '$$', 'meal': ('Dinner',)},
    {'name': 'Le_Pain', 'type': 'Bakery', 'price': '$$', 'meal': ('Lunch', 'Dinner')},
    {'name': 'Creme_Bakery', 'type': 'Bakery', 'price': '$', 'meal': ('Snack',)}
]

def get_attr(k):
    s = set()
    for r in Restaurants:
        if isinstance(r[k], tuple):
            for t in r[k]:
                s.add(t)
        else:
            s.add(r[k])
    return s

def choose_restaurant():
    categories = ', '.join(Restaurants[0])
    while True:
        choice = input(f'Select by category ({categories}) or choose random: ')
        if choice == 'random':
            return random.choice(Restaurants)
        if choice in Restaurants[0]:
            choices = get_attr(choice)
            if (v := input(f'Select value for {choice} from ({", ".join(choices)}): ')) in choices:
                op = contains if isinstance(Restaurants[0][choice], tuple) else eq
                return [r for r in Restaurants if op(r[choice], v)]
        print('Invalid selection\x07')


print(choose_restaurant())

Restaurants is now a list of dictionaries which is easy to extend. You just need to make sure that each new restaurant has the same structure (keys). Also note that the 'meal' value is a tuple even if there's a single value

Related