people = {"Jenn" : ['renter', 'large room'],
"Lana" : ['renter', 'small room'],
"Ricky" :['owner', 'large room']
}
Is there a way to access each individual value for a given key via for loop to print the stats of each person? I'm relatively new to Python and I'm having troubles searching for this exact scenario. I'm familiar with f-string formatting.
Expected output for print() or sys.stderr.write()
Jenn is the renter of a large room.
Lana is the renter of a small room.
Rickey is the owner of a large room.
Use dict.items() to loop through (key, value) tuples:
for key, value in people.items():
print(f"{key} is the {value[0]} of a {value[1]}")
You can also do that:
for first, (cat, room) in people.items():
print(f"{first} is the {cat} of a {room} room")
Related
I'm trying to ask for ingredients in a recipe via the input function. I want to store that ingredient in a dictionary, separated by quantity and ingredient. For example, an input of '3 eggs', should yield {'3': 'eggs'}.
The way i do this is with the separate() and convert_to_dict() methods.
I want to ask continuously for the ingredients by means of the input, hence the while True loop.
Basically, i do this via the following code:
ingredients_list = []
def separate(list):
for i in list:
return re.findall(r'[A-Za-z]+|\d+', i)
def convert_to_dict(list):
i = iter(list)
dct = dict(zip(i, i))
return dct
while True:
ingredient = input("Please input your ingredient: ")
ingredients_list.append(ingredient)
print(convert_to_dict(separate(ingredients_list)))
This works fine, but the only problem with it is that when i input another ingredient, the separate() and convert_to_dict() methods only seem to work for the first ingredient in the ingredient list. For example, i firstly input '3 eggs', and then '100 gr of flour', yet it only returns {'3': 'eggs'}. I'm sure there is something i'm missing, but can't figure out where it goes wrong.
I think you've got the idea of your key-value pairs the wrong way around!
Keys are unique. Updating a dictionary with an existing key will just override your value. So if you have 3 eggs, and 3 cups of sugar, how do you envision your data structure capturing this information?
Rather try doing -
{'eggs': 3} # etc.
That should sort out a lot of problems...
But that's all besides the point of your actual bug. You've got a return in your for-loop in the separate function...This causes the function to return the first value encountered in the loop, and that's it. Once a function's reached a return in exist the function and returns to the outer scope.
I'm trying to output the most popular and least popular item a store has sold. The items include: beef,chicken,egg,tuna. In my code, I've declared the variables:
beef = 0
egg= 0
tuna = 0
chicken= 0
and when a customer purchases a particular item, it would be beef+=1 and so on.
My current problem is that i dont know how to display the name of the most sold item as the function min() and max() would only show the values of thew variables. I've even tried using a dictionary where the code was:
itemsList = [beef,egg,tuna,chicken]
mostPopular = max(itemsList)
items = {"Beef":beef,"Egg":egg","Tuna":tuna,"Chicken":chicken}
for key, value in items:
if mostPopular == value:
print(key)
unfortunately, this does not work as i would receive the error "too many values to unpack" :// is there another way to obtain the most popular item?
You were almost there:
for key, value in items.items():
By default iterating over a dictionary only gives you the keys. You have to call dict.items() to get key-value pairs.
You could've also imported collections.Counter and printed Counter(items).most_common(1).
I am new to python so I wanted to know if the code I wrote for printing items inside a nested dictionary in a sorted alphabetical order is optimal especially for checking if key exists. Let me know if there is a better optimal solution
# Code
import operator
locations = {'North America': {'USA': ['Mountain View']}}
locations['Asia'] = {'India':['Bangalore']}
locations['North America']['USA'].append('Atlanta')
locations['Africa'] = {'Egypt':['Cairo']}
locations['Asia']['China'] = ['Shanghai']
# TODO: Print a list of all cities in the USA in alphabetic order.
if 'North America' in locations:
for key,value in locations['North America'].items():
if 'USA' in key:
for item in sorted(value):
print(f"{item}")
# TODO: Print all cities in Asia, in alphabetic order, next to the name of the country
if 'Asia' in locations:
for key,value in sorted(locations['Asia'].items(),key=operator.itemgetter(1)):
print(f"{value[0]} {key}")
Make these two lines your code:
print('\n'.join(sorted([x for i in locations.get('North America', {}).values() for x in i])))
print('\n'.join(sorted([x + ' ' + k for k,v in locations.get('Asia', {}).items() for x in v])))
Which outputs:
Atlanta
Mountain View
Bangalore India
Shanghai China
Dictionaries in python are unordered. Given that, I will try to help solve for your actual problem of checking for a key in a dictionary.
locations = {'North America': {'USA': ['Mountain View']}}
locations['Asia'] = {'India':['Bangalore']}
locations['North America']['USA'].append('Atlanta')
locations['Africa'] = {'Egypt':['Cairo']}
locations['Asia']['China'] = ['Shanghai']
# First we clean up all the loops.
# You are just checking if the key is in the dictionary with all the loops
if 'North America' in locations and 'USA' in locations['North America']:
for item in sorted(value):
print(f"{item}")
if 'Asia' in locations:
# Since dictionaries are unordered, we will make a list of the countries to order
countries = []
for k in locations['Asia'].keys():
countries.append(k)
# Using a similar loop to the one to print cities
for country in sorted(countries):
# Adding a dimension for cities.
for city in sorted(locations['Asia'][country]):
print(f"{country}:{city}")
The Asia dictionary should loop through each country and in alphabetical order print each country and city.
dictionaries are used because they give direct lookup of any specific key. For testing existence, you don't need to search. The downside is they are not sorted.
You iterate through all countries in north america when you already know you want usa, so ... don't do that.
print(sorted(locations['North America']['USA']))
This is better because it is O(1) lookup on the second layer when you do O(n) where n is the number of nations in that particular continent. Which admittedly isn't much so that's why they say don't optimize if you don't need to. But maybe you have a lot more data and the geography sample data was just filler.
To test for existence of a key, use "in" or write a try-except for KeyError. Python is one of the few languages where it's often better to just handle the exception.
To print all the cities in Asia, you will have to combine all the lists in asia and sort that: Combining two sorted lists in Python
You can do better by maintaining the city lists in sorted order all the time, using the bisect module. Inserting or removing in a sorted list is less work than sorting it each time, assuming you look at the list more often than you add and remove cities.
If you maintain sorted lists, you can efficiently get the sorted merge with https://docs.python.org/3.0/library/heapq.html#heapq.merge Although sadly you don't have the nation name doing that.
My structure is something like this in a YAML file:
nutrition:
fruits:
apple:
banana:
pear:
veggies:
spinach:
zucchini:
squash:
meats:
chicken:
fish:
ham:
I load this in with yaml.load()
Not sure but likely because of the colons at the end of the leaf-elements (which I'm not sure need to be there), the entire structure is a 3-level dict. I can change the YML if needed to make it more efficient.
Now, I want to quickly iterate over the structure, and based on the leaf-level element I find (e.g. 'spinach'), I want to look up another simple dict, called 'recipes', which can have the string 'spinach' as a substring of its keys. This lookup dict can have keys that say 'spinach juice' or 'spinach pie' or 'chicken spinach'.
I found a way to do this, but not sure it is the right pythonic way. Here is what I have:
for food_class in database['nutrition']:
for food in database['nutrition'][food_class]:
for key, value in recipes.items():
if re.search(food, key):
print key
Any advice/pointers to make it more efficient and/or pythonic?
You can use dict.items() so you don't need to put the dictionary lookup in the nested loop.
The foods aren't regular expressions, just strings, so use in rather than re.search().
Since you're not using the value from recipe, you don't need .items()
for food_class, foods in database['nutrition'].items():
for food in foods:
for key in recipes:
if food in key:
print(key)
If you want to search for the food as a whole word, you can use re.search(r'\b' + food + r'\b', key) or food in recipes.split(' ') as the test.
I have a dictionary with the last and first names of the authors being the key, and the book, quantity, and price being the values. I want to print them out sorted in alphabetical order by the author name, and then by the book name.
The author is: Dickens, Charles
The title is: Hard Times
The qty is: 7
The price is: 27.00
----
The author is: Shakespeare, William
The title is: Macbeth
The qty is: 3
The price is: 7.99
----
The title is: Romeo And Juliet
The qty is: 5
The price is: 5.99
I'm very new to dictionaries and can't understand how you can sort a dictionary. My code so far is this:
def displayInventory(theInventory):
theInventory = readDatabase(theInventory)
for key in theInventory:
for num in theInventory[key]:
print("The author is", ' '.join(str(n) for n in key))
print(' '.join(str(n) for n in num), '\n')
The dictionary, when printed, from which I read this looks like this:
defaultdict(<class 'list'>, {('Shakespeare', 'William'): [['Rome And Juliet', '5', '5.99'], ['Macbeth', '3', '7.99']], ('Dickens', 'Charles'): [['Hard Times', '7', '27.00']]})
fwiw, camelCase is very uncommon in Python; almost everything is written in snake_case. :)
I would do this:
for names, books in sorted(inventory.items()):
for title, qty, price in sorted(books):
print("The author is {0}".format(", ".join(names)))
print(
"The book is {0}, and I've got {1} of them for {2} each"
.format(title, qty, price))
print()
Ignoring for the moment that not everyone has a first and last name...
There are some minor tricks involved here.
First, inventory.items() produces a list of key, value tuples. I can then sort that directly, because tuples sort element-wise — that is, (1, "z") sorts before (2, "a"). So Python will compare the keys first, and the keys are tuples themselves, so it'll compare last names and then first names. Exactly what you want.
I can likewise sort books directly because I actually want to sort by title, and the title is the first thing in each structure.
I can .join the names tuple directly, because I already know everything in it should be a string, and something is wrong if that's not the case.
Then I use .format() everywhere because str() is a bit ugly.
The key is to use sorted() to sort the dictionary by its keys, but then use sort() on the dictionaries values. This is necessary because your values are actually a list of lists and it seems you want only to sort them by the first value in each sub-list.
theInventory = {('Shakespeare', 'William'): [['Rome And Juliet', '5', '5.99'], ['Macbeth', '3', '7.99']], ('Dickens', 'Charles'): [['Hard Times', '7', '27.00']]}
for Author in sorted(theInventory.keys()):
Author_Last_First = Author[0]+", "+Author[1]
Titles = theInventory[Author]
Titles.sort(key=lambda x: x[0])
for Title in Titles:
print("Author: "+str(Author_Last_First))
print("Title: "+str(Title[0]))
print("Qty: "+str(Title[1]))
print("Price: "+str(Title[2]))
print("\n")
Is that what you had in mind? You can of course always put this in a function to make calling it easier.