Sharing solutions

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

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.

1 Like

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)
def reversed_list(lst1, lst2):
  a = 1
  for i in range(1, len(lst1)+1):
    if lst1[i-1] != lst2[-i]:
      a *= 0
      break
  return bool(a)

I’ve defined the range to look more familiar - like 1-1 =[0] vs [-1], 2-1 =[1] vs [-2] etc. The function returns variable a which is equal to 1. In case the values in a pair don’t match each other, variable a turns into 0. I’ve put break here because the only inequalty in pairs is enough to conclude that lists don’t match the task, so we don’t need to run the loop further on. The function returns boolean value of variable a.

Found my code to be a different solution, so I thought I could share:

def reversed_list(lst1, lst2):
  while len(lst1) > 0:
    if lst1[0] == lst2[-1]:
      lst1.pop(0)
      lst2.pop(-1)
    else:
      return False
  return True

No need to create a third list.

Hi crookedvertex,

I saw your solution and I’d like to share another way:

def reversed_list(lst1, lst2):
new =
for index in range(len(lst1)):
if lst1[index] != lst2[len(lst2)-1-index]:
new.append(0)
else:
new.append(1)
suma = 0
for j in range(len(new)):
suma += new[j]
if suma == len(new):
return True
else:
return False

Thanks for share your knowledge!

Is this a good way to do it?
if not why not?

def reversed_list(lst1,lst2):
  index = range(len(lst1))
  lst2 = lst2[::-1]
  empty = 0
  for i in index:
    if lst1[i] == lst2[i]:
      empty += 1
  if empty == len(lst1):
    return True
  else:
    return False

wouldn’t a simple if statement work better?

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

The one idea would be to use a naive approach and iterate over one list left to right, and the other right to left, comparing and returning False if a mismatch is found. Once the loop completes successfully, return True.

In your second example there is no logic necessary since you have a reverse slice to compare to the other list, so just return the comparison (recall that all comparisons are boolean expressions meaning they yield a boolean).

return lst1 == lst2[::-1]

Keep developing your skills to parse and manipulate lists using naive approaches so you don’t become biased toward them because of seeing this. Knowing the shortcuts doesn’t make us better prograrmmers since it blinds us to things we may not yet have learned and prevents us from dedicating the time and effort to learn them. As a beginner, we do not want to simply scratch the surface. We need to mar it and take cross-sections and examine it through every lens and portal. Not much we can do with return lst1 == lst2[::-1].

2 Likes

I did this, which worked:

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

Seems simpler than the suggested solution. Any reason it is worse?

Hello,

Yours does solve the problem as well, I don’t think of it as a worse solution per say. In fact, I think it’s cool that people are posting alternative solutions and it helps everyone learn more.

Just that the objective of the code challenge is to practice one’s learning/understanding of loops. :slight_smile:

It turns out that there are (at least) three ways to implement the function: by hand, with slicing, and with the built-in reversed function. As always, the “by hand” way implementation is the ugliest :laughing:

def reversed_list_manual(L1, L2):
  if len(L1) != len(L2):
    return False
  
  n = len(L1)
  for k in range(n):
    if L1[k] != L2[n - k - 1]:
      return False
  return True
  
def reversed_list_slice(L1, L2):
  return L1 == L2[::-1]
  
def reversed_list_builtin(L1, L2):
  return L1 == list(reversed(L2))

This is what I did:

def reversed_list(lst1,lst2):
  if len(lst1) != len(lst2):
    return "Error! The length of the first list is different from the second list."
  else:
    count = 0
    for i in range(len(lst1)):
      if lst1[i] == lst2[-(i+1)]:
        count += 1
    return count == len(lst1)

my solution:

def reversed_list(a, b):
  return not any([a[i] != b[len(b) - 1- i] for i, k in enumerate(a)])

I am building a list full of booleans (false if opposite items are equal). the any function searches if at least one True value exists in the list. The not in front assures that all values in the list are False

If you change that to a generator expression instead of list comprehension, it’ll short circuit.

You could use reversed and zip for iterating through the two lists to spare yourself the indexing and the error prone math that goes with it.

You could have fewer negatives in there by using == and all (all equal vs not any not equal)

You are right, there is no point in parsing all items in both lists in order to say if lists are reversed, we should return as fast as we get a clue that this might not be true.

I like your idea of using zip (me comming from other coding languages, zip is not the functionality i normally expect to find and thus not the one to think about in the first place).

The function becomes:

def reversed_list(a, b):
  if len(a) != len(b):
    return False
  for pair in zip(a, b[::-1]):
    if pair[0] != pair[1]:
      return False
  return True

… wich becomes similar to solution of @pckg

Oh. I was thinking a bit closer to what you already had, more like simplifying an expression.

all(aa == bb for aa, bb in zip(a, reversed(b)))

You can use map too:

from operator import eq

all(map(eq, a, reversed(b)))
1 Like

True, but your code will require to loop through all items of the zip, then look at boolean list and search again if all of them are set to True. Imagine having really large objects… and the very first pair tested is already False!

both of those short-circuit

Today i learned something new! You are right, all function in Python is applied to iterator and will behave similar to our manual functions, meaning exiting as soon as it finds something false.

Thanks