Guided Project: Building Fast Queries on a CSV: The opposite result!

All in all my results are not the same. And I have struck upon something interesting! All I am wondering now is why.

Screen Link:
https://app.dataquest.io/m/481/guided-project%3A-building-fast-queries-on-a-csv/5/comparing-the-performance

My Code:

    def get_laptop_from_id(self, laptop_id):
        for row in self.rows:
            if row[0] == laptop_id:
                return row
            else:
                return None        
            
    def get_laptop_from_id_fast(self, laptop_id):
        if laptop_id in self.id_to_row:
            return self.id_to_row[laptop_id]
        else:
            return None

The solution code:

    def get_laptop_from_id(self, laptop_id):
        for row in self.rows:                 
            if row[0] == laptop_id:
                return row
        return None   #Note the difference here, I have an else: statement.
    
    def get_laptop_from_id_fast(self, laptop_id):   
        if laptop_id in self.id_to_row:            
            return self.id_to_row[laptop_id]
        return None   #Note the difference here, I have an else: statement.

After this we time the difference between the two class-methods and we should see that the fast method is faster than the no_dictionary method because a dictionary has a direct lookup structure.

What I expected to happen:

print(total_time_no_dict)                                           # step 9
print(total_time_dict)

0.5494911670684814
0.002789735794067383
As you can see dict would be a lot faster in the solutions.

What actually happened when using my method (with if else):

print(total_time_no_dict)
print(total_time_dict)

0.006408214569091797
0.010406017303466797

Using the functions from the solution notebook I got:

print(total_time_no_dict)
print(total_time_dict)

2.114551305770874
0.013440132141113281

So the answer is right and wrong, because using else speeds it up considerably.

This suggests that the method of using an else: None clause instead of a return None is faster in general and it even makes the no dictionary method faster.

Interesting stuff indeed, can anyone explain to me why this is? :smiley:
or

if you can not explain:
    return your_thoughts

Consider a list as an example -

a = [1, 2, 3, 4, 5, 6]

Now, you are trying to print a string if you find a 4 in the above list -

for item in a:
    if item == 4:
        print("Found it!")
    else:
        print("Didn't find it")

Think about what happens in the above case.

How many times will it print Didn't find it?

Now, the following implementation -

for item in a:
    if item == 4:
        print("Found it!")
print("Didn't find it")

How many times will it print Didn't find it?

Think about the above two. Work through them.

Once you get the answers to the above. Think about instead of printing something, what happens when you return something?

What happens to your code as soon as it sees a return statement?

That will lead you to understanding why your solution code is fast with that else.

If you don’t figure it out, modify the above sample code I shared above to use in a function with return statements instead of print. And using both approaches, check the result you get when you run them; not the time it takes. You will understand the difference better.

If still stuck, feel free to ask more questions. But make sure to go through the above thoroughly first.

:joy: loved this!

@the_doctor
Ah yes of course! Thank you for your thorough answer :smiley:
Then it is actually the wrong implementation of the function.

By the way you’ve actually answered my other question as well. Yeah, feeling a bit stupid and arrogant now haha.

So the else clause immediately executes and you definitely do not find your laptop. I could have thought about that, but as a philosopher I was lost in time and space again.

Maybe an idea to formulate all answers in pseudocode? :wink:

1 Like