2

If you have the following list of lists:

>> A = [[1], [2]]

And then say you assign the 2nd list to the first list by:

>> A[0] = A[1]

You end up with the following:

>> print A
[[2], [2]]

So A[0] and A[1] point to the same list now. If you append an element to the first by:

>> A[0].append(3)

You will get the following:

>> print A
[[2,3], [2,3]]

However, if you try to delete the first list by:

>> del A[0]

Then only one list is removed, as follows:

>> print A
[[1,2]]

Q1.1: Why is the behavior different? One might expect both lists to be removed.

Clearly, if one just wants to make a copy of A[1] then the following works correctly:

>> A = [[1], [2]]
>> A[0] = list(A[1])
>> print A
[[2], [2]]
>> A[0].append(3)
>> print A
[[2,3], [2]]

The problem with this is that its running time is linear with the size of the list to copy, i.e., A[1].

Q1.2: Can one copy a list from another without linear-time copy operation?

3 Answers 3

1

Q1.1.

You have to differentiate between an object and object identity. Identity is just a logical address to the memory cell of the object. When you are doing A[0] = A[1], you don't actually copy the object, but you get a new identity to the object. After A[0] = A[1], you have two identities A[0] and A[1] to the same object, so when you do A[0].append(...) or A[1].append(.), what is actually being affected is the same object.

Now about lists. Lists in Python don't hold objects. They hold identities of the objects. You can check this by comparing

sys.getsizeof([1]) and sys.getsizeof([1000000000000000000000000000000]),

both will have the same size although 10000000000000000000000000000000 is obviously heavier than 1.

What del does is, it removes an element from the list, which happens to be one of the two identities and not the object, so when you have a list that holds two identities to the same object and del one of them, you still keep the object and the other identity because the object is still referenced.

Q1.2.

If you want to copy, you can just do A[0] = A[1][:], which will assign A[0] to a slice. It should be faster. Check this.

Sign up to request clarification or add additional context in comments.

5 Comments

I would say "references" instead of "identities"; I think "references" is the more commonly used terminology?
@Vultaire It might be but "identity" is used in python's documentation, so I just used "identity" to keep it consistent.
And from @itzmeontv's answer, you can get the identity value by id(A[0]).
@TrainedScarab I might have been wrong about O(1) but it should be faster. I updated the answer.
@khajvah Interesting; I didn't see how the docs used the term. Thanks; I'll keep this in mind in the future.
0

del A[0] doesn't means to delete an entry of A[0] element And would be deleted at garbage collection. It just stand for deleting a reference link from A[0] variable to list ([2,3]).

Comments

0

Q1.1: Why is the behavior different? One might expect both lists to be removed.

del A[0] 

is not deallocating the memory of list [2,3] or nor deleting the list.It just removing tag or referevce A[0] to the list [2,3].

Q1.2: Can one copy a list from another without linear-time copy operation?

A[0] = A[1][:]

For example

A = [[1], [2]]
A[0] = A[1][:]

>>id(A[0]),id(A[1])
(140215217604552, 140215217619208)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.