How to iterate over two dictionaries at once and get a result using values and keys from both
Question:
def GetSale():#calculates expected sale value and returns info on the stock with highest expected sale value
global Prices
global Exposure
global cprice
global bprice
global risk
global shares
global current_highest_sale
best_stock=' '
for value in Prices.values():
cprice=value[1]
bprice=value[0]
for keys, values in Exposure.items():
risk=values[0]
shares=values[1]
Expected_sale_value=( (cprice - bprice ) - risk * cprice) * shares
print (Expected_sale_value)
if current_highest_sale < Expected_sale_value:
current_highest_sale=Expected_sale_value
best_stock=Exposure[keys]
return best_stock +" has the highest expected sale value"
Above is my code currently. For some reason though, it appears to be doing the first loop, then the second, then the second, then the first, then the second. It appears to do the second loop each time it gets to it before going back to the first for
loop. It is because of this that the answers I’m getting are not correct.
Answers:
The question is a bit vague, but answering the title, you can get both keys and values at the same time like this:
>>> d = {'a':5, 'b':6, 'c': 3}
>>> d2 = {'a':6, 'b':7, 'c': 3}
>>> for (k,v), (k2,v2) in zip(d.items(), d2.items()):
print k, v
print k2, v2
a 5
a 6
c 3
c 3
b 6
b 7
However, do mind that keys in dictionaries aren’t ordered. Furthermore, if the two dictionaries do not contain the same number of keys, the code above will fail.
Looking at your problem, I would suggest you to create generator expression that navigates the two dictionary in pairs and using max with a custom key to calculate sale price to evaluate expected_sale_price
and the corresponding stock
Sample Data
Prices = dict(zip(range(10), ((randint(1,100), randint(1,100)) for _ in range(10))))
Exposure = dict(zip(range(10), ((randint(1,100), randint(1,100)) for _ in range(10))))
Sample Code
def GetSale(Prices, Exposure):
'''Get Sale does not need any globals if you pass the necessary variables as
parameteres
'''
from itertools import izip
def sale_price(args):
'''
Custom Key, used with the max function
'''
key, (bprice, cprice), (risk, shares) = args
return ( (cprice - bprice ) - risk * cprice) * shares
#Generator Function to traverse the dict in pairs
#Each item is of the format (key, (bprice, cprice), (risk, shares))
Price_Exposure = izip(Prices.keys(), Prices.values(), Exposure.values())
#Expected sale price using `max` with custom key
expected_sale_price = max(Price_Exposure, key = sale_price)
key, (bprice, cprice), (risk, shares) = expected_sale_price
#The best stock is the key in the expected_sale_Price
return "Stock {} with values bprice={}, cprice = {}, risk={} and shares={} has the highest expected sale value".format(key, bprice, cprice, risk, shares)
The question isn’t well defined, and the answer accepted will fail for some dictionaries. It relies on key ordering, which isn’t guaranteed. Adding additional keys to a dictionary, removing keys, or even the order they are added can affect the ordering.
A safer solution is to choose one dictionary, d
in this case, to get the keys from, then use those to access the second dictionary:
d = {'a':5, 'b':6, 'c': 3}
d2 = {'a':6, 'b':7, 'c': 3}
[(k, d2[k], v) for k, v in d.items()]
Result:
[('b', 7, 6), ('a', 6, 5), ('c', 3, 3)]
This isn’t more complex than the other answers, and is explicit about which keys are being accessed. If the dictionaries have different key orderings, say d2 = {'x': 3, 'b':7, 'c': 3, 'a':9}
, consistent results are still given.
def GetSale():#calculates expected sale value and returns info on the stock with highest expected sale value
global Prices
global Exposure
global cprice
global bprice
global risk
global shares
global current_highest_sale
best_stock=' '
for value in Prices.values():
cprice=value[1]
bprice=value[0]
for keys, values in Exposure.items():
risk=values[0]
shares=values[1]
Expected_sale_value=( (cprice - bprice ) - risk * cprice) * shares
print (Expected_sale_value)
if current_highest_sale < Expected_sale_value:
current_highest_sale=Expected_sale_value
best_stock=Exposure[keys]
return best_stock +" has the highest expected sale value"
Above is my code currently. For some reason though, it appears to be doing the first loop, then the second, then the second, then the first, then the second. It appears to do the second loop each time it gets to it before going back to the first for
loop. It is because of this that the answers I’m getting are not correct.
The question is a bit vague, but answering the title, you can get both keys and values at the same time like this:
>>> d = {'a':5, 'b':6, 'c': 3}
>>> d2 = {'a':6, 'b':7, 'c': 3}
>>> for (k,v), (k2,v2) in zip(d.items(), d2.items()):
print k, v
print k2, v2
a 5
a 6
c 3
c 3
b 6
b 7
However, do mind that keys in dictionaries aren’t ordered. Furthermore, if the two dictionaries do not contain the same number of keys, the code above will fail.
Looking at your problem, I would suggest you to create generator expression that navigates the two dictionary in pairs and using max with a custom key to calculate sale price to evaluate expected_sale_price
and the corresponding stock
Sample Data
Prices = dict(zip(range(10), ((randint(1,100), randint(1,100)) for _ in range(10))))
Exposure = dict(zip(range(10), ((randint(1,100), randint(1,100)) for _ in range(10))))
Sample Code
def GetSale(Prices, Exposure):
'''Get Sale does not need any globals if you pass the necessary variables as
parameteres
'''
from itertools import izip
def sale_price(args):
'''
Custom Key, used with the max function
'''
key, (bprice, cprice), (risk, shares) = args
return ( (cprice - bprice ) - risk * cprice) * shares
#Generator Function to traverse the dict in pairs
#Each item is of the format (key, (bprice, cprice), (risk, shares))
Price_Exposure = izip(Prices.keys(), Prices.values(), Exposure.values())
#Expected sale price using `max` with custom key
expected_sale_price = max(Price_Exposure, key = sale_price)
key, (bprice, cprice), (risk, shares) = expected_sale_price
#The best stock is the key in the expected_sale_Price
return "Stock {} with values bprice={}, cprice = {}, risk={} and shares={} has the highest expected sale value".format(key, bprice, cprice, risk, shares)
The question isn’t well defined, and the answer accepted will fail for some dictionaries. It relies on key ordering, which isn’t guaranteed. Adding additional keys to a dictionary, removing keys, or even the order they are added can affect the ordering.
A safer solution is to choose one dictionary, d
in this case, to get the keys from, then use those to access the second dictionary:
d = {'a':5, 'b':6, 'c': 3}
d2 = {'a':6, 'b':7, 'c': 3}
[(k, d2[k], v) for k, v in d.items()]
Result:
[('b', 7, 6), ('a', 6, 5), ('c', 3, 3)]
This isn’t more complex than the other answers, and is explicit about which keys are being accessed. If the dictionaries have different key orderings, say d2 = {'x': 3, 'b':7, 'c': 3, 'a':9}
, consistent results are still given.