Returning too many index values in a nested for loop

Hey everyone,

I am having a tough time with this one.

I’ve written a nested for loop which I’m not sure is even the correct method, but I think I have my condition correct as well as the append. My return may be a little suspect.

It’s returning [0, 0, 2, 3, 4] but should be returning [0, 2, 3]. I’m not sure how that even makes sense.

Link: https://www.codecademy.com/paths/computer-science/tracks/cspath-flow-data-iteration/modules/dspath-python-loops/lessons/python-functions-loops-cc/exercises/same-index

Write a function named same_values() that takes two lists of numbers of equal size as parameters.
The function should return a list of the indices where the values were equal in lst1 and lst2 . For example, the following code should return [0, 2, 3]

same_values([5, 1, -10, 3, 3], [5, 10, -10, 3, 5])

Here is my code:

#Write your function here

def same_values(lst1, lst2):
  new_lst = []
  for index in range(len(lst1)):
    for index2 in range(len(lst2)):
      if lst1[index] == lst2[index2]:
        new_lst.append(index)
  return new_lst
  


#Uncomment the line below when your function is done
print(same_values([5, 1, -10, 3, 3], [5, 10, -10, 3, 5]))
1 Like

I found the solution through the FAQ here:

@ajax0370057080 's code showed me where my issue was, it was with the second nested ‘for’ loop. My question is however: how does ‘index’ know to iterate through lst2 when I don’t define lst2 in my ‘in’ clause/statement? I never thought lists work like that. I thought you always had to define the list in your loop using the ‘in’ statement.

My code:

#Write your function here

def same_values(lst1, lst2):
  new_lst = []
  for index in range(len(lst1)):
   if lst1[index] == lst2[index]:
    new_lst.append(index)
  return new_lst
  


#Uncomment the line below when your function is done
print(same_values([5, 1, -10, 3, 3], [5, 10, -10, 3, 5]))
1 Like

As you discovered, the nested loop was the problem in your first example, earlier. Since all we are expected to return is the indices that have matching values in both lists, and the lists are equal in length, the only thing to do is iterate a range of indices, and compare the two list elements at that respective index. Well done boiling it down to a solution along those very lines. It’s rewarding when we solve a problem through hard won intuition.


P. S. Thank you for including a link to the exercise. So much easier to address a question when we have that at our disposal.

1 Like

Spoiler Alert

When we reach the unit on iterators we can re-visit this problem. Take this as an example you might learn from at that time, not necessarily this moment.

>>> u = [9, 6, 4, 1, 2, 7, 8]
>>> v = [8, 6, 3, 1, 3, 7, 9]
>>> w = [i for i, x in enumerate(zip(u, v)) if x[0] == x[1]]
>>> w
[1, 3, 5]
>>> 

There are two iterators in there, three when we include the for..in of the comprehension. Knowing that we will by the time you get to this unit be able to emulate the iterative approach to accomplishing this same outcome should be confidence building. Oh, wait, that’s what we’re learning to do right now. How embarrassing. Bottom line, expect things to get interesting and bear down on loops in all their flavors. We need them for pretty much everything. Never discount their fundamental beauty.

>>> w = [i for i, (a, b) in enumerate(zip(u, v)) if a == b]
>>> w
[1, 3, 5]
>>> 

Annotation

                                                pack
                                               /
                                         [----]
>>> w = [i for i, (a, b) in enumerate(zip(u, v)) if a == b]
                  [----]
                 /
           unpack
2 Likes

@mtf

Gotcha, I’m not sure what enumerate does but I’m sure this will be helpful at some point.

I’ve spent a lot of time on these 11 loop problems. Purposely struggled through them, googled my way for different ideas, and asked questions here. I’m nowhere near where I would like to be, but much better than where I started. In fact I’m still struggling with the last loop problem in this exercise.

1 Like

Please post a link to that exercise, thanks.

Loops are fundamental; but, the way we use them is logical and/or imperative. The first thing to do is look at a problem and sketch on paper what you would do to solve it. A lot of these problems are those sort… Ones we can solve on paper. Our job is to translate our steps (and our thinking) into working code that can carry out those same steps.

1 Like

@mtf

Link: https://www.codecademy.com/paths/computer-science/tracks/cspath-flow-data-iteration/modules/dspath-python-loops/lessons/python-functions-loops-cc/exercises/reversed

Here is my most recent challenge.

My logic for this would be:

  1. Reverse lst2
  2. Loop through lst1
  3. Compare values in lst1 and lst2 reversed
  4. Return the original lists if they if the conditional is True
  5. Anything else will be false.

It’s easy to think of the logic but translating it into code is tough for me at the moment.

Think how you would iterate through one list from right to left while iterating through the other from left to right.

Hint

            indices

l->r   =>  0, 1, 2, 3, ...

r->l  =>  -1, -2, -3, -4, ...
1 Like

@mtf

left to right:

for i in lst:
  print(lst[i])

right to left

for i in lst[:-1]
  print(lst[i])

My idea here is that we are starting from the end of the list by using slicing.

Examine your slice. Is the order changed? Will it not still iterate left to right, only excluding the last element? Granted, a slice method would fill the bill, but would not be very explicit.

>>> [1, 2, 3, 4][::-1]
[4, 3, 2, 1]
>>> 

Way too easy. I’m thinking more in terms of how to loop from the right to the left using conventional logic.

Given a signature line,

for i in range(len(lst1)):
    # set a value for `j`

Notice that the right index is always the negative of 1 more than i. That is, when i is zero, j is -1. When i is 1, j is -2, and so on.

1 Like

I see so since j will always be some version of i but less than i. I’m not sure mathematically how I would display that using python. Right now I have i - 1 but that will only be 1 less than j. So when i is sero, j is -1 but when i is 2, j is 1 and not -2.

for i in range(len(lst1)):
  j = i - 1

We want the negative of one more than i. Consider this expression…

j = - (i + 1)
1 Like

@mtf

Makes sense. I’m not sure I’m cut out for thinking of that kind of logic, but I’ll have to remember this one.

1 Like

It’s less logic and more empirical data.

 0,  1,  2,  3,  4,  5,  6   =>  indices left to right
-7, -6, -5, -4, -3, -2, -1   =>  also indices left to right

-1, -2, -3, -4, -5, -6, -7   =>  indices right to left

The relationship between the last and first can be described with the expression above. No logic, just hard fact.

- (0 + 1)  =>  -1
- (1 + 1)  =>  -2
- (2 + 1)  =>  -3

and so on.

1 Like

I see so you’re simply just multiplying an expression by a negative expression. Thanks for clearing that up.

1 Like

Exactly. - anything is the same thing as -1 * anything only we don’t need the math since the interpreter accepts the negative sign for what it is… Negation.

1 Like

@mtf

Thank you for all your help. I wrote the rest of the code on my own, which is an improvement.

#Write your function here

def reversed_list(lst1, lst2):
  for i in range(len(lst1)):
    j = - (i + 1)
    if lst1[i] == lst2[j]:
      print (lst1[i], lst2[j])
    if lst1[i] != lst2[j]:
      return False
  return True
  

#Uncomment the lines below when your function is done
print(reversed_list([1, 2, 3], [3, 2, 1]))
print(reversed_list([1, 5, 3], [3, 2, 1]))
1 Like