1

I need to reverse the list vals without using any of python's built-in functions. The code I have right now keeps returning [9, 12, 12, 9] but when I actually use a print statement like print(vals[n]) the list is in reverse order (9, 12, -3, 7). Also, we are not allowed to return any values as you would normally with a function.

This is for a class. Please if you can let me know why my code is returning the result that it is, not just the answer.

def reverse_list(vals):

    n = len(vals)

    for index in range(len(vals)):

         #(this gives 3,2,1,0, hence reversing the index of the list or so i thought)
         n -= 1 
         vals[index] = vals[n]

vals = [7, -3, 12, 9]
reverse_list(vals)
print(vals)
Zoder
  • 13
  • 5
  • the exact wording is to reverse the list by mutating the original list. not sure if this clarifies much – Zoder May 12 '20 at 03:29

5 Answers5

3

There are two problems. Let's take a look.

Problem 1: You don't just want to copy the items at the end to the beginning because that overwrites the ones at the front. You're getting [9, 12, 12, 9] because the items at the front are being overwritten by the ones at the back.

Solution 1: Swap the elements. Python allows for a clever way of swapping two values without requiring a temporary variable:

for index in range(len(vals)):
     n -= 1 
     vals[index], vals[n] = vals[n], vals[index]

Problem 2: If you run this you might be confused because vals is unchanged:

[7, -3, 12, 9]

It looks like swapping didn't fix it. But that's because you have two problems. Swapping is correct, but it's not enough.

Before we jump to the solution, let's talk about how to diagnose the cause. A bread and butter debugging technique is inserting printouts to check intermediate results. Add a printout, make a mental prediction of what the result will be, and then run the program and see if you were right.

I might add a printout like this:

for index in range(len(vals)):
     n -= 1 
     print("Swapping vals[{}]={} with vals[{}]={}.".format(index, vals[index], n, vals[n]))
     vals[index], vals[n] = vals[n], vals[index]

I'd expect items 0 and 3 to be swapped and items 1 and 2 to be swapped. Is that what happens?

Swapping vals[0]=7 with vals[3]=9.
Swapping vals[1]=-3 with vals[2]=12.
Swapping vals[2]=-3 with vals[1]=12.
Swapping vals[3]=7 with vals[0]=9.
[7, -3, 12, 9]

Hm, that doesn't seem right. There are four swaps, not two. We swapped vals[1] with vals[2], and then vals[2] with vals[1]. Whoops!

Solution 2: You need to stop half way through the list so that you don't swap all the items twice. If you swap positions 1 and 5, say, you don't want to also swap positions 5 and 1. Loop over half of the indices and then stop.

for index in range(len(vals) // 2):
     n -= 1 
     vals[index], vals[n] = vals[n], vals[index]
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • is this line of code vals[index], vals[n] = vals[n], vals[index] the same as basically saying vals[index] = vals[n] and vals[n] = vals[index] ??? – Zoder May 12 '20 at 03:50
  • You have to do it on one line. See [Is there a standardized method to swap two variables in Python?](https://stackoverflow.com/questions/14836228/is-there-a-standardized-method-to-swap-two-variables-in-python) for a detailed explanation and some alternatives. [@MichaelButscher's comment](https://stackoverflow.com/questions/61743137/why-does-my-function-to-reverse-this-list-only-by-indexing-and-without-using-rev/61743261?noredirect=1#comment109213054_61743137) gives a common multi-line version using a temp variable. – John Kugelman May 12 '20 at 04:03
0

You can try this:

def reverse_list(vals):
    n = len(vals)
    vals2 = vals.copy()
    for index in range(len(vals)):
         print(n)
         #(this gives 3,2,1,0, hence reversing the index of the list or so i thought)
         n -= 1 
         vals2[index] = vals[n]
    print(vals2)

vals = [7, -3, 12, 9]
reverse_list(vals)
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Sachin Gupta
  • 186
  • 1
  • 14
  • This gives error "'int' object is not subscriptable" and sorry i didnt include on the post, i'm updating now. we are not allowed to return any values either – Zoder May 12 '20 at 03:20
  • You don't want to return anything? So you want to just print the reversed list? – Sachin Gupta May 12 '20 at 03:25
  • Yes, the objective is not to use built in python help or return anything like you would with a function – Zoder May 12 '20 at 03:31
0

Currently, you are writing over your list as you loop through it, so it is not giving the expected answer. See below:

Initial list: [7, -3, 12, 9]

After first loop: [9, -3, 12, 9]

After second loop: [9, 12, 12, 9]

After third loop: [9,12,12,9]

After fourth loop: [9,12,12,9]

Build a temporary list for your result:

vals = [7, -3, 12, 9]
result = []
for i in range(0,len(vals),-1):
    result.append(vals[i])
user1558604
  • 947
  • 6
  • 20
0

EXPLANATION of your program:

The initial value of n = 4 (len(vals))

The assignment details are below:

In the for loop the value of n becomes : 3 , 2 , 1 , 0

vals[index=0] = vals[n=3] = 9

vals[index=1] = vals[n=2] = 12

vals[index=2] = vals[n=1] = 12 (the value was changed to 12 in the previous assignment step)

vals[index=3] = vals[n=0] = 9 (the value was changed to 9 in the first assignment step)

hence you are getting list : [9,12,12,9]

Solution : instead use an empty list and append the number in reverse order

mugabits
  • 1,015
  • 1
  • 12
  • 22
-1

Within your function, I think it's probably better to have a list that you return. So you will still pass vals as an argument, but then it will return a new list, which will be in reverse order. So something like this:

def reverse_list(vals):
    return_list = []
    for i in reversed(vals):
        return_list.append(i)
    return return_list

From here, you will create list like you did before. Then when you want to reverse it, you do:

vals = reverse_list(vals)
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
daniel-eh
  • 344
  • 3
  • 13