How to loop through two dictionaries in Python

16,092

Solution 1

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.

Solution 2

I think the simplest solution is:

total= 0

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

print total 

Solution 3

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())
Share:
16,092
Fede Couti
Author by

Fede Couti

We are who we choose to be

Updated on June 13, 2022

Comments

  • Fede Couti
    Fede Couti almost 2 years

    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.

  • aruisdante
    aruisdante about 9 years
    isn't this making a rather large assumption about the order of an unordered set? I.E. that k == k2?
  • Padraic Cunningham
    Padraic Cunningham about 9 years
    @aruisdante, this is doing what the OP was trying to do, I am going to add an example using an OrderedDict
  • aruisdante
    aruisdante about 9 years
    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.
  • Padraic Cunningham
    Padraic Cunningham about 9 years
    @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