Why hyphen(-) behaves peculiarly in python strings? [duplicate] - python

This question already has answers here:
Python string interning
(2 answers)
Are strings cached? [duplicate]
(1 answer)
About the changing id of an immutable string
(5 answers)
Closed 4 years ago.
I found a peculiar behavior while going through Python 3 data types especially string. If two strings a and b have the same value then a is b becomes True (Strings must not contain hyphen of course).
If:
>>> a = 'string_without_hyphen'
>>> b = 'string_without_hyphen'
Then:
>>> a is b
True
>>> a == b
True
But if:
>>> a = 'string-with-hyphen'
>>> b = 'string-with-hyphen'
Then,
>>> a is b
False
>>> a == b
True
which confused me.
Why is this happening?

Because moon rays and unicorns implementation details.
The is operator compares objects by identity, not by content.
The Python implementation you're using may or may not decide to reuse the same string object for both a and b, if it feels like it, since strings are immutable in Python. The same may or may not occur for integers (and in fact, this also happens with Java's Integers if they're sufficiently small).
The gist is: never use is unless you really do need identity (address) comparison; things may be weird. Use == instead.

Related

Why 'is' operator is different when adding a value to a variable [duplicate]

This question already has answers here:
"is" operator behaves unexpectedly with integers
(11 answers)
Closed last month.
in shell environment,
x = 250
y = 250
x + 100 is y + 100
x + 100 is y + 100 result is False.
Why is the result value "False" while id(x), id(y) is same?
Also
x = 250
y = 250
x is y
x += 10
y += 10
x is y
last statement result is False. It is same problem.
I thought both questions would be True.
At a high-level, is checks whether the values refer to the same reference, while == calls a method of the objects to compare them
As a general rule, only use is when comparing against singletons
None
True
False
and == everywhere else
#Mark Ransom's comment gets to why this can have unexpected effects (such as numbers sometimes comparing the same, not not every time) .. small numbers have a special priority and are cached, though to my knowledge this is implementation-specific (and so it may vary between different interpreters and versions of Python) and should not be relied upon
>>> a = 100
>>> b = 100
>>> c = 1000
>>> d = 1000
>>> a is b
True
>>> c is d
False
"The is operator does not match the values of the variables, but the instances themselves."
Source : Understanding the "is" operator
To sum up, the values are equal but the instances isn't the same.
I recommend this lecture from Python official documentation : https://docs.python.org/3/tutorial/classes.html
is checks object identity. It is only True if you are comparing the same object on both sides. Just because two integers have the same value doesn't mean they have to be the same object. In fact, they usually aren't.
CPython optimizes a small set of integers (-5 through +256) to always be singletons. That is, whenever an integer is created, python checks whether the integer is in a small range of cached integers and uses those when possible. This is pretty quick - for small integers, which are the most commonly used integers, you don't need to create new objects. But its not scalable. Outside that range, python will generally create a new integer even if the integer already exists. The cost of lookup is too much.
The python compiler may also reuse immutables such as integers and strings that it knows about in a given compilation unit. This lookup is done once at compile and is relatively fast considering everything that goes on in that compile step.
But you can't rely on any of this. This is just how python happens to be implemented and the moment and it may change in the future. There are several singletons you can count on: None, True and False will always work.

When is it ok to check for literal values with "is" in Python? [duplicate]

This question already has answers here:
Why isn't "is" comparison used in place of "==" for primitive types?
(1 answer)
Boolean identity == True vs is True
(7 answers)
Is there only one True and one False object in Python?
(2 answers)
Closed 2 years ago.
I want to check if a variable is True (not just its truthiness).
This is easily checked like this:
>>> a = 1
>>> isinstance(a, bool) and a
False
>>> a = True
>>> isinstance(a, bool) and a
True
Of course, that is totally fine. However, the same behaviour can be seen in the following code:
>>> a = 1
>>> a is True
False
>>> a = True
>>> a is True
True
In my opinion, the second snippet is a bit more readable (if you understand how is works). With Python 3.8, I get a SyntaxWarning when executing the second snippet. Would the second example work with all Python implementations? Is there a guarantee that bool objects of the same value are identical in this way? I believe I have read somewhere that this is not guaranteed for int objects. Is it ever ok to check literal values with is like this?

string object behavior in python [duplicate]

This question already has answers here:
comparing two strings with 'is' -- not performing as expected
(3 answers)
Closed 3 years ago.
curious to know the reason for following
x='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
y='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
x is y
#output : True
x='a'*21
y='a'*21
x is y
#output : False
Q1: since string interning is done for string literals then why not for 'a'*21 ? is it not a string literal?
Q2: is it because expression 'a'*21 is evaluated at run-time and interning is done at runtime?
#
s1 = "strin"
s2 = "string"
s1+"g" is s2
# output : False
# Explaination : Above code involves a run-time concatenation, the result of which is not automatically interned
Q3: How to know if an expression is going to be evaluated at run-time or compile time?
is will return True if two variables point to the same object, == will return True if the objects referred to by the variables are equal. If you try:
s1 = "strin"
s2 = "string"
s1+"g" == s2
# True
x='a'*21
y='a'*21
x == y
True
In your first case, Python was intelligent enough to use one single object to refer to the literal string you described twice. This is generally not the case.

Different behaviors of 'is' operator when comparing variables with same int values [duplicate]

This question already has answers here:
Is there a difference between "==" and "is"?
(13 answers)
"is" operator behaves unexpectedly with integers
(11 answers)
Closed 4 years ago.
I'm playing with the 'is' operator in the interactive shell when I encountered an odd behavior with the below code:
It goes as expected at first:
>>> x = 11
>>> y = 11
>>> x is y
True
But when I tried this one:
>>> x = 987456
>>> y = 987456
>>> x is y
False
After further tries using id() function, I noticed that integers >256 points on the same object while others are not. I also noticed that this behavior only occurs in the python interactive shell. What's with this behavior?
is checks for memory address. Immutable objects that are wrappers around C type tends to have same memory address, whereas others don't. The difference here is the bytes required to store the integers.

Python is vs == [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
String comparison in Python: is vs. ==
When is the == operator not equivalent to the is operator? (Python)
I'm pretty new to Python still. I heard someone say use is, not == because "this isn't C". But I had some code x is 5 and it was not working as expected.
So, following proper Python/PEP style, when is the time to use is and when is the time to use == ?
You should use == to compare two values. You should use is to see if two names are bound to the same object.
You should almost never use x is 5 because depending on the implementation small integers might be interned. This can lead to surprising results:
>>> x = 256
>>> x is 256
True
>>> x = 257
>>> x is 257
False
The two operators have different meaning.
is tests object identity. Do the two operands refer to the same object?
== tests equality of value. Do the two operands have the same value?
When it comes to comparing x and 5 you invariably are interested in the value rather than the object holding the value.

Categories

Resources