0

After thinking a while this concept came to my mind which I was gone through few days ago.

In Python if I did x=y then automatically x and y will point same object reference location but is there any way I can manage to change y reference location but with same value if x.

for example:

x=100
y=x

now x and y share same object reference location of value 100 but I want to have a different location for y.

Edit: What I am trying to do

l1=[1,2,3,4]
l2=l1
i=0
j=len(l1)-1

while j >= 0 :
    l1[i]=l2[j]
    i=i+1
    j=j-1

    print("L1=",l1,"L2",l2,"i=",i,"j=",j)

What I am getting as outout

L1= [4, 2, 3, 4] L2 [4, 2, 3, 4] i= 1 j= 2
L1= [4, 3, 3, 4] L2 [4, 3, 3, 4] i= 2 j= 1
L1= [4, 3, 3, 4] L2 [4, 3, 3, 4] i= 3 j= 0
L1= [4, 3, 3, 4] L2 [4, 3, 3, 4] i= 4 j= -1

Thank you.

rɑːdʒɑ
  • 4,925
  • 13
  • 41
  • 77

3 Answers3

2

This is unlikely to occur with small numbers because numbers are immutable in Python and the runtime is almost assuredly going to make x and y "point to" the same object in the object store:

>>> x = 100
>>> id(x)
4534457488
>>> y = 100
>>> id(y)
4534457488

Note that even by making y reference a new copy of 100, I still got the same object.

We can try:

>>> y = 25 * (5 - 1)
>>> id(y)
4534457488

Same.

If we used something mutable like lists, we could do:

>>> x = [1, 2, 3]
>>> id(x)
4539581000
>>> y = [1, 2] + [3]
>>> id(y)
4539578440
>>> x == y
True
>>> id(x) == id(y)
False

And now you have two variables, each referencing a different object in the object store, but the object values are equal.

As wRAR points, out, copy.copy can do things much more cleanly:

>>> from copy import copy
>>> x = [1, 2, 3]
>>> id(x)
4539578440
>>> y = copy(x)
>>> id(y)
4539580232

Tada. This is more inline with what you want, but notice it might not work for immutables like numbers!

>>> from copy import copy 
>>> x = 100
>>> id(x)
4534457488
>>> y = copy(x)
>>> y
100
>>> id(y)
4534457488

My Python interpreter is just going to make one int object with value 100 in the object store.

For larger numbers, this may not be the case. I tried:

>>> x = 393
>>> id(x)
4537495408
>>> y = 393
>>> id(y)
4539235760

I found information in this S.O. question where an answerer experimented with integers on the object pool. The number of pre-cached integer objects is probably implementation dependent in Python, whereas the JVM does define caching behavior.

Community
  • 1
  • 1
Ray Toal
  • 82,964
  • 16
  • 166
  • 221
  • Excellent , but so everytime I need to slice and append y[-1] so I can point to different object location. – rɑːdʒɑ Mar 27 '16 at 06:24
  • Well appending is a mutating operation which will not change the `id` of the list. You will want to copy or use `+` to make a new list. – Ray Toal Mar 27 '16 at 06:27
2

You can not do it with int. More over:

x = 100 
y = 100
x is y
>>> True

This is like a pool of small integers. They have only single representation in the memory.

With mutable objects you may do copy() operation:

a = [1]
b = copy(a)
a is b 
>>> False 
Rudziankoŭ
  • 9,663
  • 16
  • 80
  • 173
1

You can use copy.copy() for this.

wRAR
  • 24,218
  • 4
  • 82
  • 96
  • I tried this but it did not do what the OP wants: >>> from copy import copy `>>> x = 100 >>> id(x) 4534457488 >>> y = copy(x) >>> y 100 >>> id(y) 4534457488` – Ray Toal Mar 27 '16 at 06:21
  • would you mind giving an example ? : EDIT : Ray mentioned in his answer. Its good. Thanks for pointing out wRAR. – rɑːdʒɑ Mar 27 '16 at 06:24
  • @Ray Toal, see my answer, pleae. We cannot copy "small" `int` it has single representation – Rudziankoŭ Mar 27 '16 at 06:26
  • Right. [More info here](http://davejingtian.org/2014/12/11/python-internals-integer-object-pool-pyintobject/). – Ray Toal Mar 27 '16 at 06:36