Manu
Manu

Reputation: 841

How do I reverse a part (slice) of a list in Python?

Why doesn't this work?

# to reverse a part of the string in place 
a = [1,2,3,4,5]
a[2:4] = reversed(a[2:4])  # This works!
a[2:4] = [0,0]             # This works too.
a[2:4].reverse()           # But this doesn't work

Upvotes: 51

Views: 79472

Answers (8)

Savannah Madison
Savannah Madison

Reputation: 657

To reverse an array from a particular index to another, please use this:

#start is the starting index
#end is the ending index
while start<end:
    nums[start],nums[end] = nums[end],nums[start]
    start+=1
    end-=1

All this does is that it picks one element from the start and one from the end and swaps them. Then it moves the start pointer front while the end pointer back.

Upvotes: 1

norok2
norok2

Reputation: 26886

One way of doing this purely in-place is with the good old loops:

def reverse(seq, start, stop):
    size = stop + start
    for i in range(start, (size + 1) // 2):
        j = size - i
        seq[i], seq[j] = seq[j], seq[i]


l = list(range(10))
print(l)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

reverse(l, 2, 5)
print(l)
# [0, 1, 5, 4, 3, 2, 6, 7, 8, 9]

Upvotes: 3

Albert
Albert

Reputation: 391

I believe it's worth further elaborating the reasons why

a[2:4].reverse()

does not seem to work.

In addition to the fact that a[2:4] creates a copy in the memory, it should be noted that

list.reverse()

reverses the list in place and its return type is None. If you do

print(a[2:4].reverse())

None is printed. Obviously, if you forcefully do,

a[2:4] = a[2:4].reverse()

Python would raise a TypeError. However, there does exist a copy of a[2:4] in the memory which has been reversed. It's just you have no reference to access it.

On the other hand, a[2:4] = reversed(a[2:4]) works because reversed() returns a reverse iterator.

See comments of the accepted answer for how a[2:4] being different when appearing on the left of assignment.

Upvotes: 7

Arindam Roychowdhury
Arindam Roychowdhury

Reputation: 6511

Here's a weird example and weirder solution using slicing and a bit of list fundamentals.

Problem: Reverse a list in parts of two.

I/P : [1,2,3,4,5,6]

O/P: [3,2,1,6,5,4]

Soln:

[item for i in range(0,len(l),len(l)/2) for item in l[i:i+len(l)/2][::-1]]

Problem: Reverse the letters of someones name.

E.g Harry Porter

O/p: yrraH retroP

Soln:

' '.join(map(lambda x:x[::-1], s.split()))

Upvotes: 1

Reman
Reman

Reputation: 8109

Just use the slice and reverse it.

a[2:4] = a[2:4][::-1]

Upvotes: 64

dmjalund
dmjalund

Reputation: 325

Another way you might consider is to use a reversed slice:

a[2:4] = a[3:1:-1]

Upvotes: 16

user483040
user483040

Reputation:

a[2:4] is a copy of the list a that is built using the 2,3,4 items in list a. The first two work because you are assigning the changes into those spots in the original list. The last one doesn't work because you are not affecting the original list.

Upvotes: 1

Sven Marnach
Sven Marnach

Reputation: 601539

a[2:4] creates a copy of the selected sublist, and this copy is reversed by a[2:4].reverse(). This does not change the original list. Slicing Python lists always creates copies -- you can use

b = a[:]

to copy the whole list.

Upvotes: 24

Related Questions