2

I wanted to extend the class list in python37 with some custom methods. and ended up reading the UserList cpython code. After reading it new questions arose with regards of [:] usage.

If I understand correctly the `[:]` makes a slice copy of the whole `self.data`. But I am trying to see what is the point of using `[:]` at the left side of the `=` operator.

Is there any difference between option one and two? Tried in the python interpreter, and both seem to have the same effect, am I missing something?

letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# option (1)
letters[:] = []
# option (2)
letters = []

Now it comes my questions with regards to UserList code. I added comments with questions I have.

class UserList(_collections_abc.MutableSequence):
    def __init__(self, initlist=None):
        self.data = []
        if initlist is not None:
            if type(initlist) == type(self.data):
            # NOTE: Is this if statement doing the same?
            # if isinstance(initlist, list):
                self.data[:] = initlist
                # NOTE: wouldn't in this case self.data keep a reference to initlist
                # instead of a copy?
                # self.data[:] = initlist[:]  # could one replace that line with this one?
            elif isinstance(initlist, UserList):
                self.data[:] = initlist.data[:]
                # NOTE: would this line accomplish the same?
                # self.data = initlist.data[:]
            else:
                self.data = list(initlist)
    ...
Cesc
  • 904
  • 1
  • 9
  • 17
  • Possible duplicate of [How assignment works with python list slice](https://stackoverflow.com/questions/10623302/how-assignment-works-with-python-list-slice) – tripleee Nov 07 '18 at 10:08

2 Answers2

3

They don't behave the same if you have another reference to letters.

Scenario 1: modifying letters in place.

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> lst = letters
>>> letters[:] = []
>>> letters
>>> []
>>> lst
>>> []

Scenario 2, reassigning the name letters to an empty list.

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> lst = letters
>>> letters = []
>>> letters
>>> []
>>> lst
>>> ['a', 'b', 'c', 'd', 'e', 'f', 'g']

Since names are reassigned independently, lst does not see any change.

If you had

self.data = initlist

mutations to initlist would affect self.data (since they are the same object in memory).

timgeb
  • 76,762
  • 20
  • 123
  • 145
0

When you specify a on the left side of the = operator, you are using Python's normal assignment, which changes the name a in the current context to point to the new value. This does not change the previous value to which a was pointing.

By specifying a[0:2] on the left side of the = operator, you are telling Python you want to use Slice Assignment. Slice Assignment is a special syntax for lists, where you can insert, delete, or replace contents from a list. See: How assignment works with python list slice

Maybe this helps you.

CLpragmatics
  • 625
  • 6
  • 21