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