1

I have a list, ls = [0 1 2 3 4] and I am running the following:

print(ls is ls[:])

I am getting the output as False. Why are they not the same list? When I print both versions I get the same list printed.

horro
  • 1,262
  • 3
  • 20
  • 37
aa1
  • 783
  • 1
  • 15
  • 31
  • 3
    `ls[:]` makes a complete copy of `ls`, so they're not the same object. They are equal, though: `ls == ls[:]` – alexis Oct 17 '17 at 13:43
  • 1
    Slicing creates a copy – akash karothiya Oct 17 '17 at 13:43
  • Why would a list copy have to the same id? Then they'd refer to the same list still... – OneCricketeer Oct 17 '17 at 13:43
  • `is` checks if they are the same object, which they aren't. They are copies. When you do `ls[:]` you are making a copy of the original `ls`. – Adirio Oct 17 '17 at 13:43
  • @cricket_007 no. The way the question is phrased is different -- just because the answer is the same doesn't mean its a duplicate question. Its equally possible that OP or any general reader understands `is` but not that `a[:]` is a copy operator. – gbtimmon Oct 17 '17 at 13:48
  • @gbt So, you say no, but then answer saying it basically is? I'm confused – OneCricketeer Oct 17 '17 at 13:53
  • It would be annoying (and redundant) if `a = ls[:]` did the same thing as `a = ls`; doing `a = ls[:]` is a very handy way of making a shallow copy of `ls`. FWIW, the other side of the coin is that while `ls = a` binds the name `ls` to the object named `a`, but `ls[:] = a` mutates the existing `ls` object, it doesn't replace it. – PM 2Ring Oct 17 '17 at 14:04
  • @criket_007 No I said it might be, you said it was. Calling this a duplicate is making an assumption about what the person has misunderstood -- I think its okay to point a person to that answer as it might be related. It is wrong to close it as a duplicate as it has a 50/50 chance of answering the question are therefore could be rather unhelpful and a bit reductionist. If I had come faster and called this a duplicate of https://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list would I have been any less correct? I assert strongly that this site has become too close happy. – gbtimmon Oct 17 '17 at 14:46
  • @cricket_007 Take a moment to notice that the most up voted answer references the copy operator -- which is NOT what this was marked as a duplicate as -- so it was probably closed improperly as a duplicate. – gbtimmon Oct 17 '17 at 14:50
  • @gbtimmon Well, **I** didn't close the question, the "Community" thing did. Besides, you got your answer in – OneCricketeer Oct 17 '17 at 15:54

4 Answers4

6

ls references one object in memory; ls[:] creates a new list object using the same references contained in the first.

>>> ls = [0, 1, 2, 3, 4]
>>> new_ls = ls[:]
>>> id(ls) == id(new_ls)
False
>>> id(ls[0]) == id(new_ls[0])
True
chepner
  • 497,756
  • 71
  • 530
  • 681
  • 1
    Be careful with that, `id(ls[0]) == id(0)`. Low numbers are singletons in some Python implementations to improve speed and memory usage. – Adirio Oct 17 '17 at 13:46
  • I don't think that distracts too much from the point at hand, but you can certainly replace `ls = [object(), object(), object(), object(), object()]` without changing the result. It would be a bigger issue if you were expecting `[0, 0, 0, 0, 0]` to be a list of 5 distinct references. – chepner Oct 17 '17 at 13:48
  • Right, just pointing it out. – Adirio Oct 17 '17 at 13:50
2

This is basically a duplicate of

String comparison in Python: is vs. ==

You just didnt know it.

== and is check two different things.

== asks are these two thing the same value.

is asks are these two things the same thing i.e. the same object.

a[:] copies the list creating a new list with the same value.

thus

a == a[:]
>> True

a is a[:]
>> False
gbtimmon
  • 4,238
  • 1
  • 21
  • 36
1

[:] creates a shallow copy of ls, which destroys the new list's original reference to ls. Bear in mind, however, that nested lists are not effected by [:] and thus, copy.deepcopy is required.

Example:

s = [5, 6, 2, 4]
=>s
[5, 6, 2, 4]
new_s = s
new_s.append(100)
=>new_s
[5, 6, 2, 4, 100]
=>s
[5, 6, 2, 4, 100]

Usage of deepcopy:

s = [5, 6, [5, 6, 2, 4], 4]
new_s = s[:]
new_s[2].append(45)
=>s
[5, 6, [5, 6, 2, 4, 45], 4] #both sublists are still being referenced
=>new_s
[5, 6, [5, 6, 2, 4, 45], 4]
import copy
s1 = [5, 6, [5, 6, 2, 4], 4]
new_s1 = copy.deepcopy(s1)
new_s1[2].append(100)
=>new_s1
[5, 6, [5, 6, 2, 4, 100], 4]
=>s1
[5, 6, [5, 6, 2, 4], 4]
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
1

[:] denotes slicing of a list (slice from start till end) which creates a shallow copy of your iterable object. To demonstrate further: When you create a list a = [1] and do b = a, here you are simply reassigning name of a to b where a and b both point o same memory address

>>> a = [1,2]
>>> b = a
>>> id(a)
140177107790232
>>> id(b)
140177107790232
>>> b.remove(1)
>>> a
[2]

But if you do it with slicing:

>>> a = [1,2]
>>> b = a[:]
>>> id(a)
140177107873232
>>> id(b)
140177107873304
>>> b.remove(1)
>>> a
[1, 2]
>>> 
MohitC
  • 4,541
  • 2
  • 34
  • 55