0

I want to reverse a list from the kth element IN PLACE and here's my code:

list[:] = list[len(list) - k:] + list[:len(list) - k]

I know that this is the right code while the following code is incorrect. Anyone know why?

list = list[len(list) - k:] + list[:len(list) - k]

Thanks!

Vimanyu
  • 625
  • 2
  • 9
  • 24
CathyQian
  • 1,081
  • 15
  • 30

1 Answers1

1

The difference is a reflection of the assignment syntax as specified in the python language reference. Your first example generates a modified copy of the list and sets the contents of your list to the contents of the copy. The second example generates a modified copy and assigns the list identifier to point to that copy.

You can see this more clearly by calling id on your list before and after:

id(list)
list[:] = list[len(list) - k:] + list[:len(list) - k]
id(list)  # prints the same id as above

id(list)
list = list[len(list) - k:] + list[:len(list) - k]
id(list)  # prints a new id representing a new list object

In the second case, list has a different id because it actually represents a new list object, where the first reuses the list and only updates the contents.

With that being said, notice that in both cases a copy of the list is being made so you aren't really gaining anything. Neither update is truly being calculated in-place. For this reason, in 99% of cases I would go with the second more concise syntax.

Furthermore the 'in place' version involves updating potentially many elements within the list, where just updating the list identifier is always a single update. You can see the small performance overhead from the extra copy work with the following experiments:

$ python -m timeit 'x=range(100000); x[:]=x[::-1]'
100 loops, best of 3: 3.62 msec per loop
$ python -m timeit 'x=range(100000); x=x[::-1]'
100 loops, best of 3: 2.62 msec per loop

$ python -m timeit 'x=range(10); x[:]=x[5:] + x[:5]'
1000000 loops, best of 3: 1.31 usec per loop
$ python -m timeit 'x=range(10); x=x[5:] + x[:5]'
1000000 loops, best of 3: 1.02 usec per loop
avigil
  • 2,218
  • 11
  • 18