Python 3 integer addresses [duplicate] - python

This question already has answers here:
The `is` operator behaves unexpectedly with non-cached integers
(2 answers)
Closed 1 year ago.
x=300
y=300
print(id(x),id(y))
a=[300,300]
print(id(a[0]),id(a[1]))
On executing above code I get different addresses for x and y but the same address for a[0] and a[1]. Can anyone tell me why that is happening?

Take a look at below example:
>>> a=256
>>> b=256
>>> print(id(a),id(b))
(31765012, 31765012)
>>>
>>> c=257
>>> d=257
>>> print(id(c),id(d))
(44492764, 44471284)
>>>
This will help you understand the unexpected behavior for integers. Whenever you create a int in range -5 to 256 you actually just get back a reference to the existing object. This is called Integer Caching in python.
In CPython, the C-API function that handles creating a new int object is PyLong_FromLong(long v). see the documentation on this link
EDIT: Now coming to the list. For the same list elements (larger integers) you are getting same id's because list is created at once or you can say in one go.
You can achieve similar behavior with integers as well, see below example with parallel assignment.
>>>
>>> a,b = 300,300
>>>
>>> print(id(a),id(b))
(36132288, 36132288)
>>>
Hope this will clear your doubts.

Related

Python unnecessary string allocation [duplicate]

This question already has answers here:
What are the rules for cpython's string interning?
(2 answers)
Python string interning
(2 answers)
Why and where python interned strings when executing `a = 'python'` while the source code does not show that?
(1 answer)
Closed last year.
When you assign same string literal to two variables, Python only allocates one string. This is very reasonable since string is immutable object in Python.
>>> a = "Hello"
>>> b = "Hello"
>>> id(a)
4311984752
>>> id(b)
4311984752
>>> a is b
True
But the strange part is: when the string contains special character (like !), Python will allocate two strings with exact same content.
>>> a = "hi!"
>>> b = "hi!"
>>> id(a)
4328663024
>>> id(b)
4317237616
>>> a is b
False
I read about this strange behaviour from here: https://python-course.eu/python-tutorial/data-types-and-variables.php
But that guide didn't elaborate why Python does this seemingly unnecessary duplicated string allocation.
My question is what's rationale behind Python's design of duplicated string allocation for string containing special character?

*= multiplier question between arrays and integers [duplicate]

This question already has answers here:
Why does += behave unexpectedly on lists?
(9 answers)
Closed 1 year ago.
I'm trying to learn coding through some tutorials and encountered something curious as I'm going over operators. The basic ones I get, but some others (like *= here) throw me off.
a = 1
b = a
a *= 2
print(a)
print(b)
Output
2
1
But when a is an array, this happens:
a = np.array([1, 2, 3, 3, 5, 5])
b = a
a *= 2
print(a)
print(b)
Output
[2 4 6 6 10 10]
[2 4 6 6 10 10]
Any insight as to why this happens? I can't really find much about it. The only thing I came across was "coercion rules"; does the second instance happen because a is being assigned to an array but then to an integer? Or is it a matter of the print statement order?
It's probably trivial but I'm just curious, thanks!
The Simple answer to your question is,
There are two kinds of objects in Python: Mutable objects and Immutable objects. The value of a mutable object can be modified in place after it’s creation, while the value of an immutable object cannot be changed.
Immutable(Not Modifiable) Object: int, float, long, complex, string tuple, bool
Mutable(Modifiable) Object: list, dict, set, byte array, user-defined classes.
So,here in your case firstly a and b are immutable objects as it belongs to class int in python,"b=a" means b is pointing towards a address,and as you update value of a to a*=2, the value is store on new memory location, but b is still pointing towards older address, thats why b is not showing changed value of a.
For more understanding of memory management in python, please read this blog, thankyou :)
https://medium.com/#tyastropheus/tricky-python-i-memory-management-for-mutable-immutable-objects-21507d1e5b95

Python (int) and (int,) [duplicate]

This question already has answers here:
How to create a "singleton" tuple with only one element
(4 answers)
Closed 3 years ago.
Why type((1)) is int and not a tuple? Whereas type((1,)) gives tuple.
That's also an answer to the question why we should use commas while defining a tuple with one value. Because tuples are not like lists which is unique in a way that we define it (using squared brackets) we have to add the comma to the value. In the first one type((1)) inner paranthesis have no effect, so it's just a basic integer nothing else. Like when you define expressions in paranthesis to give them priority. Hope it helps :)
Python compiler treated (1) as 1 because of that it is showing as int. that is inbuilt behavior of python compiler.
>>> a = (1)
>>> print(a)
1
>>> a = (1,)
>>> print(a)
(1,)

Python slice without copy? [duplicate]

This question already has answers here:
Can I create a "view" on a Python list?
(10 answers)
Closed 8 years ago.
Is there a way to create a "slice view" of a sequence in Python 3 that behaves like a regular slice but does not create a copy of the sliced part of the sequence? When the original sequence is updated, the "slice view" should reflect the update.
>>> l = list(range(100))
>>> s = Slice(l, 1, 50, 3) # Should behave like l[1:50:3]
>>> s[1]
4
>>> l[4] = 'foo'
>>> s[1] # Should reflect the updated value
'foo'
I can write my own Slice class that does this but I wanted to find out if there was a built-in way.
Use islice from itertools library
EDIT:
I see where I misunderstood the question.
Well, there is no such thing. If you want to create your class, you'll have to:
Keep a reference to the original list in you Slice class
Define, __iter__, __getitem__ and __setitem__ methods to work on the original list with index conversion

Understanding python's memory model [duplicate]

This question already has answers here:
Is a variable the name, the value, or the memory location?
(5 answers)
Closed 9 years ago.
Consider the following log:
>>> y = 20000
>>> id(y)
36638928
>>> y = 1000000
>>> id(y)
36639264
As you can see, after changing the value of y, it's id changed as well.
Does it mean that int is immutable? what is happening behind the scenes?
Thanks!
Yes, integers are immutable. What you need to realize is that:
A variable is simply a name which you use to reference an object.
20000 and 1000000 are two unique integer objects. This means that they will never share the same memory address simultaneously.
In simple terms, when you execute this line:
y = 20000
two things happen:
An integer object 20000 is created in the object space.
A name y is created in the namespace and pointed to that object.
When you execute this one:
y = 1000000
two more things happen:
A new integer object 1000000 is created in the object space.
The name y is changed to point to that object instead of 20000.

Categories