What does ":=" do?
It's called list slicing:
[from:to:skip]
[from:to]
So if I say:
list = range(20)
print list[1:3] #returns [2, 3]
print list[1:12:3] #returns [2, 5, 8, 11]
print list[14:] #because theres no end: [15, 16, 17, 18, 19]
print list[14:-2] #-2 from the end: [15, 16, 17]
Python permits you to "slice" various container types; this is a shorthand notation for taking some subcollection of an ordered collection. For instance, if you have a list
foo = [1,2,3,4,5]
and you want the second, third, and fourth elements, you can do:
foo[1:4]
If you omit one of the numbers in the slice, it defaults to the start of the list. So for instance
foo[1:] == [2,3,4,5]
foo[:4] == [1,2,3,4]
Naturally, if you omit both numbers in the slice you will get the entire list back! However, you will get a copy of the list instead of the original; in fact, this is the standard notation for copying a list. Note the difference:
>>> a = [1,2,3,4]
>>> b = a
>>> b.append(5)
>>> a
[1, 2, 3, 4, 5]
>>>
>>> a = [1,2,3,4]
>>> b = a[:]
>>> b.append(5)
>>> a
[1, 2, 3, 4]
This occurs because b = a
tells b
to point to the same object as a
, so appending to b
is the same as appending to a
. Copying the list a
avoids this. Notice that this only runs one level of indirection deep -- if a
contained a list, say, and you appended to that list in b
, you would still change a
.
By the way, there is an optional third argument to the slice, which is a step parameter -- it lets you move through the list in jumps of greater than 1. So you could write range(100)[0::2] for all the even numbers up to 100.
That will create a shallow copy of the list, and return it.
"Shallow copy", as opposed to "deep copy", means the list will only create new copies of the references in it, not the actual objects. That is, a new list with the same object references will be created, but the objects themselves will remain the same.
If you remove an item from the original the new list won't be affected, but if you alter one of the elements inside the original list (by calling a method or setting an object property, for example), the element will also change on the new list, because although they are different lists, they point to the same objects.
If self.var
is a mutable sequence, it will return a shallow copy of that sequence.
If self.var
is an immutable built-in sequence such as a string
or a tuple
, most implementations will return self.var
itself.