Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is `var[:] = []` different from `var = []`? [duplicate]

I normally understand how slices behave to the left and right of the assignment operator.

However, I've seen this in the Python (3.8.0) manual and trying to figure out what I'm missing.

clear the list by replacing all the elements with an empty list

letters[:] = []

How's that different from just letters = []?

(It's not easy to search for [:] as stackoverflow thinks you're looking for a tag. So, if there is already an answer I couldn't locate it.)

I see some rather irrelevant answers. So, to hopefully clarity, the question is not about what the [:] slice means, rather about assigning the empty list to one.

like image 835
tonypdmtr Avatar asked Nov 06 '19 11:11

tonypdmtr


3 Answers

This code demonstrates what is going on:

original = ['a','b','c']

letters = original

print('Same List')
print(original)
print(letters)

letters = []

print('Different lists')
print(original)
print(letters)

letters = original

letters[:] = []

print('Same list, but empty')
print(original)
print(letters)

Output:

Same List
['a', 'b', 'c']
['a', 'b', 'c']
Different lists
['a', 'b', 'c']
[]
Same list, but empty
[]
[]

The first part of the code: letters = original means that both variables refer to the same list.

The second part: letters = [] shows that the two variables now refer to different lists.

The third part: letters = original; letters[:] = [] starts with both variables referring to the same list again, but then the list itself is modified (using [:]) and both variables still refer to the same, but now modified list.

like image 146
quamrana Avatar answered Oct 19 '22 18:10

quamrana


The assignment var = [] binds the name var to the newly created list. The name var may or may not have been previously bound to any other list, and if it has, that list will remain unchanged.

On the other hand, var[:] = [] expects var to be already bound to a list, and that list is changed in-place.

That's why the behaviour in these two cases is different:

var1 = [1, 2, 3]
var2 = var1
var1 = []
print(var1, var2)  # prints [] [1, 2, 3]

var1 = [1, 2, 3]
var2 = var1
var1[:] = []
print(var1, var2)  # prints [] []
like image 30
bereal Avatar answered Oct 19 '22 18:10

bereal


var = [] is an assignment to the name var. It replaces what, if anything, var used to refer to with [].

var[:] = [] is a method call in disguise: var.__setitem__(slice(), []). It replaces the elements referred to by the slice (in this case, all of them) with the elements in [], effectively emptying the list without replacing it altogether.

Incidentally, you can use var.clear() to accomplish the same thing; slice assignment more generally lets you replace one range of values with another, possibly longer or shorter, range of values.

like image 5
chepner Avatar answered Oct 19 '22 18:10

chepner