FAQ: Code Challenge: Loops - Reversed List


#22

Thanks a lot, It’s much more clear now! :grinning: :sweat_smile:

I remember it was covered but failed to remember…


#23

I am able to solve most of these but I am often going about it much differently than I see in the comments.

def reversed_list(lst1, lst2):
–i = v = 0
–if len(lst1) == len(lst2):
----for num in lst1:
------while i < len(lst1):
--------rev = lst2.pop()
--------if lst1[i] == rev:
----------i += 1
--------else:
----------i += 1
----------v += 1
–else:
----v += 1
if v != 0:
–return False
else:
–return True


#24

Should there really be two loops there? Seems to me like you’d iterate over one of the lists, and then you’re done, there’s nothing to repeat.

There are also two places you could exit early: failing the length check (avoids nesting the rest of the code inside an if-statement), and upon finding a difference (avoids having to count, either it exits early, or they are the same)

One of the buttons in the post editor is for telling the forum to not re-format things.


#26

I honestly don’t have a clue why this line works, specifically the - index part. I understand the rest of the code just fine when I read it out loud…

if lst1[index] != lst2[len(lst2) - 1 - index]:

What does - index do exactly? All I know so far is that we take any index from lst1 and if not equal to the last index of lst2 - index(???).


#27

lets say we have the following two lists:

lst1 = ['a', 'b', 'c', 'd', 'e']
lst2 = ['e', 'd', 'c', 'b', 'a']

lst1 is the same as lst2 in reverse. Now we have to express this into code

what we need to do:

  • compare first item of lst1 with last item of lst2
  • compare second item of lst1 with second to last item of lst2
  • compare last item item of lst1 with first item of lst2

(... represents everything in between, i was too lazy to write them all)

this exactly what this if condition does, for the first iteration of the loop, index will be zero, so then we get:

if lst1[0] != lst2[len(lst2) - 1 - 0]:

lets do the math first, lst2 has a length of 5 (sticking with the example i started this post with). 5 - 1 - 0 is 4, so we get:

if lst1[0] != lst2[4]:

now we resolve the square brackets, which gives us the values from the lists based on indexes:

if 'a' != 'a':

these are equal, so the lst1 could still be the same as lst2 in reverse, so we continue to the next iteration of the loop, index has now become 1:

if lst1[1] != lst2[len(lst2) - 1 - 1]:
# resolving math
if lst1[1] != lst2[3]:
# getting values/resolving square brackets
if 'b' != 'b':

these are equal, so the lst1 could still be the same as lst2 in reverse. Here we compared the second value of lst1 with the second to last value of lst2.

This continues until we completed all the elements from the list, or one of the values doesn’t equal, in which case lst1 isn’t the same as lst2 in reverse, in which case we should return False


#28

Ohh now I get it, thank you for your through explanation! Some of these concepts really need some time to sink in.


#29

I found this to be the easiest way.
Decided to check if anyone else had the same idea but I didn’t see it here so I figured I’d share.

def reversed_list(lst1, lst2):
  if lst1 == lst2[::-1]:
    return True
  else:
    return False

#30

given a comparison gives a boolean value as result, we can just return that:

def reversed_list(lst1, lst2):
  return lst1 == lst2[::-1]

#32

I created an empty list in which i could store every True value. This would add a True value to that list (line 7) every time there was a match. In line 8 I compared the length of the list with the counted amount of True’s. This would then return True if every comparison was a match and False otherwise.
Is there any weak point in this code? I am wondering because it differs from the original solution


#33

Counting the amount of matches will cause it to ignore where the matches are, won’t it? You’d for example get the result that [1, 2] is the reverse of [1, 2] which it isn’t, due to having the same elements.
[1, 1] is also the reverse of [1, 1] but your function probably says that it’s not due to the number of matches being 4
Also seems like far too many comparisons. How many comparisons should be made with regard to the size of the input?

Whether it matches the “solution” is kind of irrelevant. Is it doing the right thing? Would you be doing those things if you did it manually? What is the right thing to do? Ask yourself what should happen and refer to that when you write the code.


#34

Thanks for the comments. I thought this code would result in the same output that was give as the original solution. I was struggling with the exercise which resulted in me trying another approach. I think I tried too hard to make the example lists fit the code that I lost sight of the bigger picture. Thanks anyways :+1:


#35

A possible solution:

#Write your function here
def reversed_list(lst1, lst2):
  lst3 = []
  for n in lst2:
    lst3.insert(0, n)
  print(lst1, lst2, lst3)
  if lst1 == lst3:
    return True
  else:
    return False
 
#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]))
print(reversed_list([2, 7, 3, 1], [1, 3, 7, 2]))
print(reversed_list([2, 7, 3, 1], [1, 7, 3, 2]))

And this generates and checks automatically the pair of lists:

##########
#This imports the random module for the random list generator.
import random

##########
# Random list generator.
# Generates a list with 5 integer numbers, among 0 and 9.
# The variable "ctrl" controls the while loop condition.
# You can generate larger lists changing the while loop condition.
def random_list_generator():
  ctrl = 0
  lst = []
  while ctrl != 5:
    ctrl += 1
    lst.append(random.randint(0, 9))
  return lst

##########
# Checks if "lst2" is the reversed version of "lst1".
# Generates a specular list of "lst2" called "lst3", and cheks if "lst1" (...)
# (...) and "lst" are equal.
# Returns "True" or "False".
def reversed_list(lst1, lst2):
  lst3 = []
  for n in lst2:
    lst3.insert(0, n)
  if lst1 == lst3:
    return True
  else:
    return False

##########
# Variable "x" controls the main while loop.
# Variable "iterations" permits both while loop control and information (...)
# (...) about how many iterations need the while loop to find a positive (...)
# (...) result (= "True").
# The results will be printed if there is a positive match.
# The iterations are caped at 1.000.000 for avoid infinite loops.
x = 1
iterations = 0

while x == 1 and (iterations <= 10**6):
    random_list1 = random_list_generator()
    random_list2 = random_list_generator()
    if reversed_list(random_list1, random_list2) == False:
        iterations += 1
    else:
        iterations += 1
        x = 0
        print(reversed_list(random_list1, random_list2),
              random_list1, random_list2, iterations)

#36

This is what I did…

the other way i.e. “the hint”, while I can see what it does…sort of…confuses me.


#38

can we not also use .reverse() and compare? is there something wrong with this?

def reversed_list(lst1,lst2):
  lst2.reverse()
  if lst1 == lst2:
    return True
  else:
    return False

#39

Can anyone please help me in understanding why my code is not working:

def reversed_list(lst1,lst2):
  lst2rev = lst2[-1::-1]
  for index in range(len(lst1)):
    if lst1[index] != lst2rev[index]:
      return False
    return True

it’s returning True for this list - print(reversed_list([1, 5, 3], [3, 2, 1])).

The problem is it is only reading the first index i.e. lst1[0] and comparing 0th index of the reversed list. Can you please help in explaining why it’s not iterating over rest of the indexes.

Thank you


#41

return is the keyword used to pass back a return value to the caller of the function. After doing so, the function is done, kind of like handing in an exam

if the return keyword is nested in a loop, the return keyword will simply “stop” the loop. Like an exam where you haven’t completed all the questions but you decide to hand the test in (return it to the teacher)


#42

Thank you for the explanation, however there have been cases of loops where return is used and the loop has iterated over all the elements without returning after the first one. So in this code which I posted earlier what should I modify - I used print in place of return and in the output I get comparison between each and every element of the two lists, printing True/False 5 times.
This is the code in the answer to the problem, and this one is working just fine despite using return -

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

#43

except in this case, return True is outside the loop, where in your case it was nested in the loop.

which gives quite a difference, the correct solution only gives true when lst2 is lst1 in reverse

your function gives true if the first item of lst1 equals the last item of lst2.


#44

And now for a spot of silliness…

>>> a = [3, 5, 7]
>>> b = [8, 5, 3]
>>> c = zip(a, b[::-1])
>>> d = map(lambda x: set(x), c)
>>> e = filter(lambda x: len(x) != 1, list(d))
>>> list(e)
[{8, 7}]
>>> a = [3, 5, 7]
>>> b = [7, 5, 3]
>>> c = zip(a, b[::-1])
>>> d = map(lambda x: set(x), c)
>>> e = filter(lambda x: len(x) != 1, list(d))
>>> list(e)
[]
>>> 

#45

Thank you so much! This explains.