-2

from this answer https://stackoverflow.com/a/1207461/8074522 I'm trying to find the difference between using

somelist = [1,2,3,4,5,6,7,8,9]
somelist = [x for x in somelist if x>4]
and 
somelist[:] = [x for x in somelist if x>4]

in his answer, he is saying

Or, by assigning to the slice somelist[:], you can mutate the existing list to contain only the items you want:

"to contain only" < I can use assign to the somelist without slicing.

So what's the need of somelist[:] here?

hellow
  • 12,430
  • 7
  • 56
  • 79
Ahmed Younes
  • 964
  • 12
  • 17
  • 1
    Assigning to `somelist` **does not** change the list that that name used to refer to, whereas assigning to `somelist[:]` does. Which is right for your case will depend on the details of your needs. – jonrsharpe Jul 02 '18 at 11:20

2 Answers2

1

@jonsharpe gave a terse answer in the comment, but to illustrate this clearly:

Assign a new list. Loses the reference to the old list object and creates a new one:

>>> lst1 = [[1, 2, 3],[4, 5, 6]]
>>> lst2 = lst1
>>> lst1 = [[7,8,9]]
>>> lst1 is lst2
False
>>> lst1
[[7, 8, 9]]
>>> lst2
[[1, 2, 3], [4, 5, 6]]

Assign to slice. Replaces the list (or a part of the list, depending on what the slice is) in-place, keeping the same object.

>>> lst1 = [[1, 2, 3],[4, 5, 6]]
>>> lst2 = lst1
>>> lst1[:] = [[7,8,9]]
>>> lst1 is lst2
True
>>> lst1
[[7, 8, 9]]
>>> lst2
[[7, 8, 9]]
Leo K
  • 5,189
  • 3
  • 12
  • 27
1

Instruction like somelist = [1,2,3,4,5,6,7,8,9] creates a new list and assigns it (the whole list) to your variable (somelist).

The second case, somelist = [x for x in somelist if x>4] is just filtering. The for loop assigns each element from this list to a temporary variable x.

Then (inside this loop) if checks whether this (current) element meets some condition, in your case, whether it is greater than 4.

Only if it is, this element is added to the new array, which finally will be assigned to somelist.

And now what is the difference between plain assignment (just to somelist) and the slice assignment ( to somelist[:]).

Imagine that initially there was otherList and you created your somelist using plain assignment: somelist = otherList.

Actually, no second list has then been created, but somelist may be regarded as another "pointer to" that first list.

In other words, both otherList and somelist point to the same internal object (in this case, array).

Then, later in your code, if you used somelist[:] = ... you write new content to the same internal object, so this new content is visible also using otherList (e.g. in other part of your code).

But if you used plain assignment (somelist = ...), then:

  • There is created a new internal object (array) and somelist points just to it.
  • The old content is still visible as otherList.

So as jonrsharpe pointed out, the decision which option to use depends on what your application really needs.

In the simplest case, if you have no other variable pointing to the "old" array, you can use plain assignment (IMHO a more natural option) and the old array (now with no reference from any other variable) will be garbage collected.

Valdi_Bo
  • 30,023
  • 4
  • 23
  • 41
  • @leo he said "Replaces the list in-place and keeping the same object.. it was not clear till you explained in better way .. Thanks for all of you , Appreciated – Ahmed Younes Jul 02 '18 at 12:52