2

There is some confusion regarding this. Consider this piece of code.

>>> g=[[10]*3]*3
>>> f=[[10,10,10]]*3
>>> id(g)==id(f)
False
>>> id(g[0][0])==id(f[0][0])
True

Also, consider this piece of code.

>>> g=[['Aamir']*3]*3
>>> f=[['Aamir','Aamir','Aamir']]*3
>>> id(g)==id(f)
False
>>> id(g[0][0])==id(f[0][0])
True

If f and g are different objects, then how can their inner elements point to the same memory location?

Tonechas
  • 13,398
  • 16
  • 46
  • 80
Aamir Khan
  • 324
  • 2
  • 10

2 Answers2

5

As your question evolved, different iterations of it require different answers:

None

None is a singleton, so all references to it refer to the same object and have the same address. This means that, for a given Python process, id(None) always returns the same value. It also means that we can test for None using the is operator:

<expression> is None

Strings

Strings are subject to interning, where the interpreter folds identical string literals to conserve storage. More on this in Python string interning.

The way this happens to be implemented means that your string example breaks if we replace one of the literals with an expression involving a variable:

>>> aami='Aami'
>>> g=[[aami+'r']*3]*3
>>> f=[['Aamir','Aamir','Aamir']]*3
>>> id(g)==id(f)
False
>>> id(g[0][0])==id(f[0][0])
False

Integers

Interestingly, CPython also chooses to intern small integers:

>>> x=1
>>> y=1
>>> x is y
True
>>> x=100000
>>> y=100000
>>> x is y
False

More on this in "is" operator behaves unexpectedly with integers.

Concretely, this means that your first example breaks if we try it with much larger integers:

>>> g=[[100000]*3]*3
>>> f=[[100000,100000,100000]]*3
>>> id(g)==id(f)
False
>>> id(g[0][0])==id(f[0][0])
False
NPE
  • 486,780
  • 108
  • 951
  • 1,012
3

Because None doesn't change homes. Every None object has the same location. Try

>>>check = None
>>>id(check) == id(f[0][0])

You'll get:

>>>True
Sam Chats
  • 2,271
  • 1
  • 12
  • 34