-4

What is the difference between those lines?

>>> my_list = []
>>> my_list[:] = []
>>> my_list[:][:] = []
>>> my_list[:][:][:] = []
>>> my_list[:][:][:][:] = []
>>> my_list[:][:][:][:]... = []
User
  • 1,978
  • 5
  • 26
  • 47
  • The first one won't fail if you haven't defined `mylist` yet? – jonrsharpe Aug 13 '14 at 10:29
  • 1
    You are just copying the empty array over and over with Python's slice notation. Read more here: http://stackoverflow.com/questions/509211/pythons-slice-notation – chrki Aug 13 '14 at 10:29
  • 2
    Thanks for answers. I'm confusing why I'm getting so many minus votes. – User Aug 13 '14 at 10:34
  • 1
    You're getting downvoted because the question is rather trivial - you can look up things like this in the official documentation, and also trivially try them out in the interactive interpreter. As your question did not indicate that you did any of those things, it suggests a severe lack of research and thus is prime downvote material. – l4mpi Aug 13 '14 at 10:36
  • I don't think that question is trivial. I know that notation of `[:]` means _copy_, but I couldn't find out what `list[:] = other_list` means . – User Aug 13 '14 at 10:39
  • It is documented that this means _slice assignment_ when used on the left hand side of an assignment operation; it's not that hard to find this in the docs even though it arguably is a lesser-known feature of python. But even if it were completely undocumented, **you could have simply tried variations of this exact code in the interactive interpreter** to find out what it does. – l4mpi Aug 13 '14 at 10:43
  • 2
    @l4mpi: unless you understand the fundamental Python principle that everything is an object and that names are just references to those objects, trying out the above code makes no apparent difference. – Martijn Pieters Aug 13 '14 at 10:47
  • 1
    @l4mpi: in all cases `my_list` remains an empty list; the fact that the difference between 1 and 2 is that `my_list` references a new list vs. the existing list is not obvious, nor is it obvious that the rest of the variants make no visible changes when you use an empty right-hand-side list object. That can be very confusing unless you have studied Python in more depth than a casual reading of the documentation gives you. Putting those concepts together (from disparate parts of the documenation) is not trivial. – Martijn Pieters Aug 13 '14 at 10:49
  • @MartijnPieters this is why I said _variations_ of the code; e.g. using lists filled with different things; using different objects than lists, etc. Trying out something like this should be second nature to any programmer. And besides, that fundamental python principle is just another researchable thing that is already documented in thousands of SO questions and elsewhere... – l4mpi Aug 13 '14 at 10:50
  • @l4mpi: you could say that for all programming languages and principles; the trick is hitting on the right combo of things to try out and building a mental model. You and I already have the mental model built up making it easier to grok, but I can see where someone new to these concepts is coming from and where Stack Overflow can help. – Martijn Pieters Aug 13 '14 at 10:54
  • @MartijnPieters well, OP gives no indication of having tried anything at all, or having invested any effort other than copypasting the code to SO and asking "what's the difference". He doesn't describe his attempted understanding of what's going on; it's not even clear from the question that he knows what assignment is. And also, not having a mental model for something like this doesn't mean OP is excused for not trying anything; just as an OP who doesn't know how to debug something isn't magically allowed to use SO as a debugging service. All this combined is of course a downvote reason. – l4mpi Aug 13 '14 at 11:03
  • @l4mpi: sure, there is no indication that there was more research into this here, and that is perhaps a valid reason to down vote. I am merely saying that I can *understand* why reading the documentation would not have led to understanding. – Martijn Pieters Aug 13 '14 at 11:06

1 Answers1

2
  1. my_list = [] creates a new list object and binds the name my_list to it. If anything was bound to my_list before that reference is now gone.

  2. my_list[:] = [] requires my_list to already be bound to a list object (or other type that supports slice assignment); all indices contained in that list object are replaced by the indices in the other list object on the right-hand-side. In this case both lists are empty, so there is no actual change, but if my_list had any contents they would have been cleared now.

  3. my_list[:][:] = [] first selects a slice from the existing my_list object, producing a new list object, then applies step 2 to that result. The new list object is then discarded again.

The rest are just variants of 3, with the selection being applied multiple times.

To illustrate, change what is contained in my_list. First step 1:

>>> my_list = [1, 2, 3]
>>> other_reference = my_list
>>> other_reference is my_list
True
>>> my_list = ['new', 'list']
>>> my_list is other_reference
False
>>> other_reference
[1, 2, 3]

The my_list name was bound to a new list object, the list object itself, still referenced by other_reference was unchanged.

Step 2 changes the list object itself:

>>> my_list = [1, 2, 3]
>>> other_reference = my_list
>>> my_list[:] = [4, 5]
>>> my_list is other_reference
True
>>> other_reference
[4, 5]
>>> my_list
[4, 5]

All indices in the list object were replaced, and other references to the same list object see the change.

Step 3 makes no changes, as a copy is altered instead:

>>> my_list = [1, 2, 3]
>>> other_reference = my_list
>>> my_list[:][:] = [4, 5]
>>> my_list is other_reference
True
>>> my_list
[1, 2, 3]
>>> my_list[:][:][:] = ["won't", 'matter']
>>> my_list
[1, 2, 3]
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343