Am using This and doing
if sheet.row_values(rownum)[0] is not 'Value':
....print sheet.row_values(rownum)[0]
After I do that, I still get Value printed. Could it be that the sheet.row_values(rownum)[0] value is not a string? Or why is the If statement not working?
is is testing the identity of an object.
if I am to write:
a = 1
b = 1
a is b # not guaranteed to be true
This is because the variable itself may point at different data, which is your case.
Using the == equality operator would give you the desired results, because it would actually look at the contents, not the strings identifier.
Note when you are comparing a variable to None, the is operator is okay, because there is actually only ever one None object.
Related
So the is keyword returns true only if the two arguments point to the same object. My question is related to the snippet below.
This snippet
number = None
if number is None:
print("PEP 8 Style Guide prefers this pattern")
Outputs
>>PEP 8 Style Guide prefers this pattern
Does this mean when I assign number = None then it is only by reference, because is checks if it is the same object. I'm so confused why this happens?? Am I wrong?? Why was this design choice made?
This is because of two reasons.
1. Assignments in Python are by reference.
In the following code
x = object()
y = x
print(x is y) # True
print(id(x)) # 139957673835552
print(id(y)) # 139957673835552
Calling object() creates a new structure in memory, whose unique identifier can be accessed with the id() function.
You can imagine x and y being arrows pointing to the same object, and this is why their underlying identifier is the same in both cases.
As such, when assigning None to a variable, you're just saying "number is an alias, an arrow pointing to the object returned by writing None". You can check that
number = None
print(id(None), id(number))
will give you the same identifier two times. But wait! What if you do it for a big number like 100000?
number = 100000
print(id(100000), id(number)) # Different values!
This means that the same literal, written two times, can return different objects, bringing up the next reason.
2. The language guarantee for None
Note that no matter how many times you get the None identifier, you get the same one.
print(id(None)) # 139957682420224
print(id(None)) # 139957682420224
print(id(None)) # 139957682420224
This is because writing None doesn't create a new object, as in the first example, because the language specification guarantees that there's only one possible object of NoneType in memory. In other words, there's only one possible object returned by writing None, making comparisons with is work as expected. This is a good design choice: There's only one canonical way for saying that a variable (an arrow) points to nothingness.
In fact, using is is encouraged as the Pythonic way of checking that a variable is None.
You can also get the class of the object by writing
NoneType = type(None)
and notice how
NoneType() is None
is true.
Note: The uniqueness property is also satisfied by other literals, particularly small numbers, for performance reasons.
All assignments are by reference (see Facts and myths about Python names and values). However, the language guarantees that None is the only object of its type. That value is created at startup, and the literal None will always produce a reference to that value.
>>> a = None; b = None
>>> a is b
True
>>> a = None
>>> b = None
>>> a is b
True
Compare to a literal like 12345, which may or may not produce a reference to an existing value of type int.
>>> a = 12345; b = 12345
>>> a is b
True
>>> a = 12345
>>> b = 12345
>>> a is b
False
Why this produces different results isn't really important, other than to say that an implementation can create new objects from int literals if it prefers.
This is about the following type of statement:
b = np.array([1,2,3,4])
def func(a=None):
if a is None:
a = b
which I would like to replace the if statement with:
def func(a=None):
a = a or b
so firstly two things: I can't do the above as an argument default because I need the default value to be evaluated at runtime (i.e if the default value is actually an object attribute that is expected to change). Secondly, I heard that maybe the way I want to do it is not always recommended by convention, but I'm just asking from a more hypothetical perspective how to make the above work. So far I've always been writing it the first way, but in my honest opinion the second feels better.
a = a or b above fails because in this case, a is expected to be an array or pandas.DataFrame, so it gives me the standard truth value of an array is ambiguous error. It would work if a and b were floats for example.
So is there some way to write the above similarly to how I'm doing (and concisely), but to use the fact that arrays/lists of non-zero length are evaluated as true in python (i.e it would work if a was a list for example?
You can use the tertiary operator and compute the truth value yourself. Assuming a is an array for example:
a = a if a is not None and all(a) else b
where you can replace the truth logic if you like.
This question already has answers here:
Why does comparing strings using either '==' or 'is' sometimes produce a different result?
(15 answers)
Closed 9 years ago.
I noticed a Python script I was writing was acting squirrelly, and traced it to an infinite loop, where the loop condition was while line is not ''. Running through it in the debugger, it turned out that line was in fact ''. When I changed it to !='' rather than is not '', it worked fine.
Also, is it generally considered better to just use '==' by default, even when comparing int or Boolean values? I've always liked to use 'is' because I find it more aesthetically pleasing and pythonic (which is how I fell into this trap...), but I wonder if it's intended to just be reserved for when you care about finding two objects with the same id.
For all built-in Python objects (like
strings, lists, dicts, functions,
etc.), if x is y, then x==y is also
True.
Not always. NaN is a counterexample. But usually, identity (is) implies equality (==). The converse is not true: Two distinct objects can have the same value.
Also, is it generally considered better to just use '==' by default, even
when comparing int or Boolean values?
You use == when comparing values and is when comparing identities.
When comparing ints (or immutable types in general), you pretty much always want the former. There's an optimization that allows small integers to be compared with is, but don't rely on it.
For boolean values, you shouldn't be doing comparisons at all. Instead of:
if x == True:
# do something
write:
if x:
# do something
For comparing against None, is None is preferred over == None.
I've always liked to use 'is' because
I find it more aesthetically pleasing
and pythonic (which is how I fell into
this trap...), but I wonder if it's
intended to just be reserved for when
you care about finding two objects
with the same id.
Yes, that's exactly what it's for.
I would like to show a little example on how is and == are involved in immutable types. Try that:
a = 19998989890
b = 19998989889 +1
>>> a is b
False
>>> a == b
True
is compares two objects in memory, == compares their values. For example, you can see that small integers are cached by Python:
c = 1
b = 1
>>> b is c
True
You should use == when comparing values and is when comparing identities. (Also, from an English point of view, "equals" is different from "is".)
The logic is not flawed. The statement
if x is y then x==y is also True
should never be read to mean
if x==y then x is y
It is a logical error on the part of the reader to assume that the converse of a logic statement is true. See http://en.wikipedia.org/wiki/Converse_(logic)
See This question
Your logic in reading
For all built-in Python objects (like
strings, lists, dicts, functions,
etc.), if x is y, then x==y is also
True.
is slightly flawed.
If is applies then == will be True, but it does NOT apply in reverse. == may yield True while is yields False.
I came to know that any object in python has the same id irrespective of the place it is used.
a=5
print id(5)==id(a)
This statement prints True.
a='hillo'
b='hello'
c=b.replace('e','i') #this gives c='hillo'
print id(a)==id(c)
This statement prints False. But why?
I came to know that any object in python has the same id irrespective of the place it is used.
That statement is completely false.
Small integers have their ID based on their immutable value and first occurrence in the program, because their values are small and Python caches them. That is why your first example returned True.
However, in your second example, you are comparing the IDs of two different (immutable) Strings, and that's why it returns False. In general, a new String (literal) instance creates a new String object each time, hence creating a different ID.
As String are in python, method replace() returns a copy of the string to another address in which the occurrences of old have been replaced with new. That's why there are two different id. Another similar case:
>>> p = "ooo"
>>> q = "ooovooo"
>>> r = p + "vooo"
>>> r
'ooovooo'
>>> q
'ooovooo'
>>> id(q) == id(r)
False
Python assign new address to r where concatenation of p and "vooo". Thats why both are different string.
This question already has answers here:
How is the 'is' keyword implemented in Python?
(11 answers)
Closed 8 years ago.
s="wall"
d="WALL".lower()
s is d returns False.
s and d are having the same string. But Why it returned False?
== tests for equality. a == b tests whether a and b have the same value.
is tests for identity — that is, a is b tests whether a and b are in fact the same object. Just don't use it except to test for is None.
You seem to be misunderstanding the is operator. This operator returns true if the two variables in question are located at the same memory location. In this instance, although you have two variables both storing the value "wall", they are still both distinct in that each has its own copy of the word.
In order to properly check String equality, you should use the == operator, which is value equality checking.
"is" keyword compares the objects IDs, not just whether the value is equal.
It's not the same as '===' operator in many other languages.
'is' is equivalent to:
id(s) == id(d)
There are some even more interesting cases. For example (in CPython):`
a = 5
b = 5
a is b # equals to True
but:
c = 1200
d = 1200
c is d # equals to False
The conclusion is: don't use 'is' to compare values as it can lead to confusion.
By using is your are comparing their identities, if you try print s == d, which compares their values, you will get true.
Check this post for more details: String comparison in Python: is vs. ==
Use == to compare objects for equality. Use is to check if two variables reference the exact same objects. Here s and d refer to two distinct string objects with identical contents, so == is the correct operator to use.