While I like your approach to solving this problem, I see a couple of issues we should take a look at. The first issue is with the use of break
. And while removing it does not provide a solution, I just wanted to point out how it is affecting your algorithm. Check out the code chunks below to see the difference.
laptop1 = ''
laptop2 = ''
counter = 0
for price1, list1 in price_to_name.items():
for price2, list2 in price_to_name.items():
total = price1 + price2
laptop_a = list1[0]
laptop_b = list2[0]
counter += 1
if total == 5000 and (laptop_a != laptop_b):
laptop1 = laptop_a
laptop2 = laptop_b
break
print(counter)
Output: 400
And now without break
:
laptop1 = ''
laptop2 = ''
counter = 0
for price1, list1 in price_to_name.items():
for price2, list2 in price_to_name.items():
total = price1 + price2
laptop_a = list1[0]
laptop_b = list2[0]
counter += 1
if total == 5000 and (laptop_a != laptop_b):
laptop1 = laptop_a
laptop2 = laptop_b
print(counter)
Output: 160000
So what does this all mean? Well, in the first code block, the nested loops ran for a total of 400 iterations, which is the same as len(price_to_name)
. This tells us that the outer loop only ran for the first item in price_to_name
(ie price1=1340
and list1='MacBook Pro'
) and never moved on to the next items in price_to_name
. In other words, as it stand right now, this nested loop will only try combinations of prices for the first element against all other elements in the dictionary. We don’t want this.
Compare this to the second code block (with break
removed) we see that it ran for a total of 160000 iterations, which is equivalent to 400*400. In other words, it is comparing every price against every other price in price_to_name
…which is what we want! Alright, so we should start by removing break
.
Ok, so far so good? We know we want to remove break
so that we are trying all possible combinations. But it still doesn’t produce a solution…so…why not?!
Well, this is where a more critical flaw comes into play: what happens if there aren’t two laptops with different prices that sum to $5000 BUT there are two different laptops with the same price that sum to $5000? How will our code deal with that situation? Let’s walk through it.
If two different laptops have prices that sum to $5000, that means that their price is $2500 each, which means they have the same key in price_to_name
. Therefore, price1
= price2
= 2500
and as a consequence, list1
= list2
. This also implies that laptop_a
must be the same as laptop_b
since they are both being assigned as the first item in list1
and list2
(which are equivalent lists). In other words, list1[0]
== list2[0]
is True
. Under these conditions, the if
statement will never be executed since laptop_a != laptop_b
will always evaluate to False
.
So to recap, if there aren’t two laptops with different prices but there are two laptops with the same price, the variables laptop1
and laptop2
will never be assigned a value; they will remain empty strings.
Now the million dollar question is: how do we fix it? Well, the simplest way to modify the code we have already would be to add an elif
clause to deal with the situation I just described above.
My advice: construct an elif
clause that deals with the situation where the total is $5000 and list1
is the same as list2
and also make sure that the list has more than one element in it. That last part of the clause is important since it essentially checks to make sure there are two different laptops in the list. If those conditions are met, assign values to laptop_a
and laptop_b
by selecting different elements in the list by using different indices.
I don’t feel my answer would be truly complete unless I were to mention that there is a much simpler way to solve this problem without using nested loops. As you saw above with the counter
variable, nested loops can be computationally expensive and therefore we should try to avoid them if possible. That said, I really want you to solve it using your own approach first!
Let me know how you make out and if there’s anything else I can help you understand.