简体   繁体   中英

Having some errors with Loops of dictionaries in Python

I want to make a wine menu program giving the 1) name and 2) price of wine if the customers are putting the wine name with Python 3. To do this, I made a wine list consisting of dictionaries as below.

wine = [
{'Origin': 'A', 'Name': 'w1', 'price': 10000},
{'Origin': 'B', 'Name': 'w2', 'price': 2000},
{'Origin': 'C', 'Name': 'w3', 'price': 4000},
{'Origin': 'D', 'Name': 'w3', 'price': 55000},
{'Origin': 'E', 'Name': 'w2', 'price': 63000},
{'Origin': 'F', 'Name': 'w6', 'price': 80000}
]

wish_wine = input('Insert the wine what you want to have : ')

The algorithm I'm trying to realize is as follows:

1) Try to search for the all elements in the list whether there is a wine the customer wants:

2) If there is in the list, return all the results with their name and price.

3) If there is no wine in the list, print 'Sorry, there is no wine...' message

for i in range(len(wine)):
    if wish_wine in wine[i]['Name']:
        print('wine', wine[i]['Name'], 'is', wine[i]['price'], '$'.)
else:
    print('Sorry, there is no wine what you want.')

Here are the codes that I made for now, it works well in case of 3), but it also shows 'Sorry, there is no wine...' message even in the case of 2).

Thank you!

You're missing a break statement or a flag indicating you found the results.

Also, instead of iterating over range(len(wine)) you may iterate straight over the wine list, which returns a single wine for each iteration. This will make your code more readable, maintainable and efficient:

wines_found = False
for w in wine:
    if wish_wine in w['Name']:
        print('wine', wine['Name'], 'is', wine['price'], '$'.)
        wines_found = True

if not wines_found:
    print('Sorry, there is no wine what you want.')

Keep in mind that if your wine name is "Merlot" and you check M in "Merlot" you will find that it passes. This will become an issue if you have multiple wines starting wtih M .

If you wish to avoid it, change if wish_wine in w['Name'] to if wish_wine == w['Name'] , and add a break .

Perhaps you specifically intended to use this JSON-like data structure, but did you consider a hash table lookup schema?

>>> wine = [
...     {'Origin': 'A', 'Name': 'w1', 'price': 10000},
...     {'Origin': 'B', 'Name': 'w2', 'price': 2000},
...     {'Origin': 'C', 'Name': 'w3', 'price': 4000},
...     {'Origin': 'D', 'Name': 'w3', 'price': 55000},
...     {'Origin': 'E', 'Name': 'w2', 'price': 63000},
...     {'Origin': 'F', 'Name': 'w6', 'price': 80000}
... ]
>>> 
>>> wine_dict_lookup = {row['Name']: {'Origin': row['Origin'], 'price': row['price']} for row in wine}
>>> wine_dict_lookup
{'w1': {'Origin': 'A', 'price': 10000}, 'w2': {'Origin': 'E', 'price': 63000}, 'w3': {'Origin': 'D', 'price': 55000}, 'w6': {'Origin': 'F', 'price': 80000}}
>>> wish_wine = input('Insert the wine what you want to have : ')
>>> try:
...     print('wine', wish_wine, 'is', wine_dict_lookup[wish_wine]['price'], '$')
... except KeyError:
...     print('Sorry, there is no wine what you want.')
... 
wine w1 is 10000 $

This problem lends itself really well to a hash table, like a dictionary. Although, if you intend the line if wish_wine in wine[i]['Name']: to serve as a sort of fuzzy-lookup tool (ie to be able to match a string like "I want w1 ", then the different in performance between these two approaches is negligible.

The real benefit of using a dictionary is that lookups are O(1) , meaning constant-time with respect to how many different wines you have. Your list-lookup is O(n) , where n is the number of elements in your wine list, because you're iterating through potentially all wines to find the one that someone looked for.

You can use collections.defaultdict to restructure your dictionary to order by wine name. This only works if you are looking for an exact name match.

from collections import defaultdict

wine_d = defaultdict(list)

for item in wine:
    wine_d[item['Name']].append(item)

Then accessing information for an input wine name is trivial:

wish_wine = input('Insert the wine what you want to have : ')

print(wine_d.get(wish_wine, 'No wine found'))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM