5

I have provided 4 different ways to fill these lists with the same value:

var = 'a'
print('var id: ', id(var))                # var id:  1561191205488

lst1 = [var]
lst2 = ['a']
lst3 = []
lst3.append(var)
lst4 = []
lst4.append('a')

print(lst1.__sizeof__(), id(lst1[0]))      # 48 1561191205488
print(lst2.__sizeof__(), id(lst2[0]))      # 48 1561191205488
print(lst3.__sizeof__(), id(lst3[0]))      # 72 1561191205488
print(lst4.__sizeof__(), id(lst4[0]))      # 72 1561191205488

print(lst1 == lst4 == lst3 == lst4)        # True

I know that in Python everything is passed by reference and in those lists, the actual value that the list stores is a reference to the object 'a', and they are all the same (as I printed the ID's).

I expected that at least 'lst2' and 'lst4' and also 'lst1' and 'lst3' have the same memory usage, but they don't! It seems like the append method does something more than storing the reference...

Could anyone tell me what's going on here?

Boann
  • 48,794
  • 16
  • 117
  • 146
S.B
  • 13,077
  • 10
  • 22
  • 49
  • 5
    List `append` over-allocates so as to achieve amortized `O(1)` behavior. – John Coleman Nov 06 '20 at 17:36
  • @JohnColeman whoa. never knew that. – Underoos Nov 06 '20 at 17:38
  • 1
    @Underoos I don't know the details, but that is probably the issue. The source is [here](https://github.com/python/cpython/blob/master/Objects/listobject.c) but OP's question is still interesting. `Append` doesn't *always* allocate (which would defeat the `O(1)`), but perhaps appending from an empty list always leads to an allocation. – John Coleman Nov 06 '20 at 17:42
  • @JohnColeman Thanks sir. That was the exact answer I was looking for. – S.B Nov 06 '20 at 18:38

0 Answers0