python homework interleaving list

Question:

The problem statement is:

Design and implement an algorithm that displays the elements of a list
by interleaving an element from the beginning and an element from the
end.

For example, input:

1 2 3 4 5 6 7 8

Output :

1 8 2 7 3 6 4 5

This is what I tried, but I don’t know what happen with elements 7 and 8:

lista = [1, 2, 3, 4, 5, 6, 7, 8]

for i in range(len(lista)):
  lista.insert(2*i-1,lista.pop())

print("The list after shift is : " + str(lista))

# output:
# The list after shift is : [1, 7, 2, 8, 3, 6, 4, 5]
Asked By: Manuel Deza

||

Answers:

The only error in you code, is that range(len(lista)) starts from 0, not from 1. By starting from zero, in the first iteration 2*i-1 will be 2*0-1 = -1, and hence lista.insert(-1,lista.pop()), which means inserting at the very end of the list (that is what index -1 means in python).

To fix your code, you just need to start the range from 1. Actually, you are iterating too much, you can have your range just from 1 to the half of your list, like this:

lista = [1, 2, 3, 4, 5, 6, 7, 8]
for i in range(1, len(lista)//2):
  lista.insert(2*i-1,lista.pop())

print("The list after shift is : " + str(lista))

# output:
# The list after shift is : [1, 8, 2, 7, 3, 6, 4, 5]

When you become more familiarized with the language, you will see that this can be accomplished much more easily.

For example, you can use the python slice syntax to achieve your goal. You slice from beginning to half , and from end to half (step of -1), then zip then together and flat.

[i for z in zip(lista[:4],lista[:-5:-1]) for i in z]
# [1, 8, 2, 7, 3, 6, 4, 5]
Answered By: Rodrigo Rodrigues

Another option:

import math

lista = [1, 2, 3, 4, 5, 6, 7, 8]

ans = []
for i in range(math.floor(len(lista)/2)):
    ans.append(lista[i])
    ans.append(lista[-i-1])


if (len(lista) % 2) != 0:
    ans.append(lista(math.ceil(len(lista)/2)))

print(ans)
Answered By: Cezar Peixeiro

Technically speaking, I’d say it’s two off-by-one errors (or one off-by-one error, but from -1 to +1, you’ll see what I mean in the second paragraph). The first one is that you’re subtracting 1 when you shouldn’t. In the case when i = 0 (remember that range(n) goes from 0 to n-1), the insert position is being evaluated as 2*0-1 = (2*0)-1 = 0-1= -1 (for insert() method, that’s the last position of the original list, pushing what was there forward, so it’ll be the penultimate position of the NEW list).

But, when you remove the -1, the output becomes 8 1 7 2 6 3 5 4, which is close to what you want, but not quite right. What’s missing is that the elements inserted should be at positions 1, 3, 5, 7, and not 0, 2, 4, 6. So, you’ll actually need to add 1.

So, the shortest change to fix your code is to change lista.insert(2*i-1,lista.pop()) to lista.insert(2*i+1,lista.pop()).

Notice: if you put a print inside for, you’ll realize that, after changing half the elements, the output is already right. That’s because when len(lista) is 8, and you do lista.insert(x, lista.pop()) where x is bigger than 8, basically you’re removing the last element (pop) and adding it at the end, so, nothing changes. Hence, you could also change range(len(lista)) to range(len(lista)//2). Test if it’ll work when len(lista) is odd

Answered By: user19513069
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.