8

Here is an example:

l = [1, 5, 9, 3]
h = l

h[0], h[2] = h[2], h[0]

print(h) # [9, 5, 1, 3]
print(l) # [9, 5, 1, 3]

h = h*2
print(h) # [9, 5, 1, 3, 9, 5, 1, 3]
print(l) # [9, 5, 1, 3]

My understanding was that calling setting h = l would simply point h at the same item in memory that l was pointing at. So why is it that in the last 3 lines, h and l don't give the same results?

TheRealFakeNews
  • 7,512
  • 16
  • 73
  • 114

7 Answers7

9

That's quite simple to check, run this simple test:

l = [1, 5, 9, 3]
h = l

h[0], h[2] = h[2], h[0]

print(h)  # [9, 5, 1, 3]
print(l)  # [9, 5, 1, 3]

print id(h), id(l)
h = h * 2
print id(h), id(l)

print(h)  # [9, 5, 1, 3, 9, 5, 1, 3]
print(l)  # [9, 5, 1, 3]

As you can see because of the line h = h * 2, the h's id has been changed

Why is this? When you're using * operator it creates a new list (new memory space). In your case this new list is being assigned to the old h reference, that's why you can see the id is different after h = h * 2

If you want to know more about this subject, make sure you look at Data Model link.

user
  • 5,370
  • 8
  • 47
  • 75
BPL
  • 9,632
  • 9
  • 59
  • 117
5

The assignment does make h point to the same item as l. However, it does not permanently weld the two. When you change h with h = h * 2, you tell Python to build a doubled version elsewhere in memory, and then make h point to the doubled version. You haven't given any instructions to change l; that still points to the original item.

Prune
  • 76,765
  • 14
  • 60
  • 81
4

h = h * 2 assigns h to a new list object.

You probably want to modify h in-place:

h *= 2
print(h) # [9, 5, 1, 3, 9, 5, 1, 3]
print(l) # [9, 5, 1, 3, 9, 5, 1, 3]
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
1

Anytime you assign to a variable, its identity (memory address) generally changes - the only reason why it wouldn't change is that you happened to assign it the value that it already held. So, your statement h = h * 2 caused h to become an entirely new object - one whose value happened to be based on the previous value of h, but that's not actually relevant to its identity.

jasonharper
  • 9,450
  • 2
  • 18
  • 42
1

It's tricky, but when you multiply a list, you are creating a new list.

l = [1, 5, 9, 3]
h = l

'l' and 'h' are now referring to the same list in memory.

h[0], h[2] = h[2], h[0]

print(h)  # [9, 5, 1, 3]
print(l)  # [9, 5, 1, 3]

You swapped the values in h, so the values are changed in l. This makes sense when you think about them as different names for the same object

h = h * 2

print(h)  # [9, 5, 1, 3, 9, 5, 1, 3]
print(l)  # [9, 5, 1, 3]

When multiplying h * 2, you are creating a new list, so now only l will be the original list object.

>>> l = [1, 5, 9, 3]
>>> h = l
>>> id(h) == id(l)
True
>>> id(h)
139753623282464
>>> h = h * 2
>>> id(h) == id(l)
False
>>> id(h)
139753624022264

See how the id of h changes after the multiplication? The * operator creates a new list, unlike other list operation, such as append() which alter the current list.

>>> h.append(1000)
>>> id(h)
139753623282464    # same as above!

Hope this helps!

Will
  • 4,299
  • 5
  • 32
  • 50
0
import numpy as np
print np.may_share_memory(l,k)

helps in confirming if two variables l and k share the same memory

0

For anyone looking up how to test if two variables actually point to the same memory address, use the is keyword.

In the case of a python list, is also applies. Alternatively for lists, an element-wise (deep) comparison can be performed using the == operator.

Here's an example:

>>> j = [1, 2, 3, 456]
>>> i = j
>>> i == j  # element-wise comparison
True
>>> j is i  # both variables point to the same memory address
True
>>> i is j
True

Now we assign i to another list even though it has the same elements

>>> j = [1, 2, 3, 456]
>>> i = [1, 2, 3, 456]
>>> i == j  # element-wise comparison
True
>>> i is j  # do they point to the same memory address?
False
TheBaker
  • 83
  • 8