4

I want to make a for loop that can go through two dictionaries, make a calculation and print the result. This is the code:

price = {
    "banana": 4,
    "apple": 2,
    "orange": 1.5,
    "pear": 3
    }

inventory = {
    "banana": 6,
     "apple": 0,
     "orange": 32,
     "pear": 15
    }

for k, v in price, inventory:
    total = total + price*inventory
    print total

I want to know how much money would I make if I sold every item in this "store". I have already checked here but it didn't work out for me.

The error message is this:

Traceback (most recent call last):
  File "python", line 15, in <module>
ValueError: too many values to unpack

Line 15 is the one where the for loop starts. I don't know if I'm thinking how to do it in the right way.

Community
  • 1
  • 1
Fede Couti
  • 281
  • 2
  • 3
  • 13

6 Answers6

8

You can zip the dicts:

for k, k2 in zip(price,inventory):
    print(price[k]*inventory[k2])

even if your code worked you would be accessing the keys not the values so you would need to access the dict values using each key as above.

If you are using python2 you can use itertools.izip:

from itertools import izip
for k, k2 in izip(price,inventory):
    print(price[k],inventory[k2])

Because dicts are unordered you need to use an orderedDict to make sure the keys matched up.

If the dicts both have the same keys a simpler solution would be use the keys from one dict to get the values from both.

for k in price:
    print(price[k]*inventory[k])

which can be written as:

total = sum(price[k]*inventory[k]for k in price)

If you control how the dicts are created combining both into one dict storing a dict of dicts using price and inventory as keys would be a better overall solution.

shop_items = {'orange': {'price': 1.5, 'inventory': 32}, 'pear': {'price': 3, 'inventory': 15}, 'banana': {'price': 4, 'inventory': 6}, 'apple': {'price': 2, 'inventory': 0}}

Then to get the total:

print(sum(d["price"] * d["inventory"] for d in shop_items.itervalues()))

Or print all available items:

for k, val in shop_items.iteritems():
    pri,inv = val["price"],val["inventory"]
    print("We have {} {}'s available at a price of ${} per unit".format(inv,k,pri))

We have 32 orange's available at a price of $1.5 per unit
We have 15 pear's available at a price of $3 per unit
We have 6 banana's available at a price of $4 per unit
We have 0 apple's available at a price of $2 per unit

If you are dealing with money you should really use the decimal library.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • 1
    isn't this making a rather large assumption about the order of an unordered set? I.E. that `k == k2`? – aruisdante Jan 28 '15 at 22:50
  • 1
    @aruisdante, this is doing what the OP was trying to do, I am going to add an example using an OrderedDict – Padraic Cunningham Jan 28 '15 at 22:51
  • Sure, but if the dicts always have the same set of keys, it would be much more efficient to simple make a single dictionary `items = { 'name' : (price, quantity) }`. I would assume the desire for two dictionaries is to allow for more prices than items in inventory, but maybe not. – aruisdante Jan 28 '15 at 22:54
  • @aruisdante, I suppose it all depends where and the the original dicts are created the simplest solution is just getting the keys from one dict – Padraic Cunningham Jan 28 '15 at 22:55
2

I think the simplest solution is:

total= 0

for key in prices:
  total += prices[key]*stock[key]

print total 
bunbun
  • 2,595
  • 3
  • 34
  • 52
Ray Asu
  • 21
  • 1
1

If we assume the keys in inventory are always a subset of the keys in price (or at least that it's an error condition if they aren't), then you simply need to do the following:

total = 0
for item, quantity in inventory.iteritems(): #just use .items() in python 3
    try:
        item_price = price[item]
        total     += item_price*quantity
    except KeyError as e:
        print('Tried to price invalid item' + str(e))
        raise
print('Total value of goods: $' + str(total))

This can be converted to a simple one-liner if we don't care about error conditions:

total = sum(price[item]*quantity for item, quantity in inventory.iteritems())
aruisdante
  • 8,875
  • 2
  • 30
  • 37
0
total = 0
for i in range(len(price.keys())):
    total += price[price.keys()[i]] * inventory[price.keys()[i]]
print total
Malik Brahimi
  • 16,341
  • 7
  • 39
  • 70
0

You can use dict.items to get the items of both dictionary then zip the items and add the corresponding prices :

>>> map(lambda x:x[0][1]+x[1][1], zip(price.items(), inventory.items())
... )
[33.5, 18, 10, 2]

Also you can save it in a separate dictionary with a dictionary comprehension :

>>> s={k[0]:k[1]+v[1] for k,v in zip(price.items(), inventory.items())}
>>> s
{'orange': 33.5, 'pear': 18, 'banana': 10, 'apple': 2}
Mazdak
  • 105,000
  • 18
  • 159
  • 188
0

Sorry for the late reply but thought I could help others that stumble upon this question.

This looks like one of the lessons from Codecademy.

Since both dictionaries have the same keys you can loop through both dicts to get your total like below.

total = 0
for fruit in price:
    total = total + (price[fruit] * inventory[fruit])
return total