Behavior of max() with string parameters? [duplicate] - python

This question already has answers here:
How does Python 2 compare string and int? Why do lists compare as greater than numbers, and tuples greater than lists?
(2 answers)
Closed 7 years ago.
maximum = max(1, 1.25, 3.14, 'a', 1000) - why is it giving 'a' as the answer? Shouldn't 'a' get converted to ASCII and be checked?
maximum = max(1, 2.15, "hello") gives "hello" as answer. How does this answer come?

From the documentation -
CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don’t support proper comparison are ordered by their address
Hence str is always greater than int .
Some more examples -
>>> class test:
... pass
...
>>> t = test()
>>> 'a' > 5
True
>>> t > 'a'
False
>>> type(t)
<type 'instance'>
>>> t > 10
False
>>> type(True)
<type 'bool'>
>>> True > 100
False
>>> False > 100
False
Please note the type name of test class' object is instance that is why t > 5 is False .

Because strings in Python 2 are always greater than numbers.
>>> "a" > 1000
True
In Python3 it's actually fixed, they are incomparable now (because there is actually no way to compare 42 and "dog").

Related

The is keyword in python [duplicate]

This question already has answers here:
Why does comparing strings using either '==' or 'is' sometimes produce a different result?
(15 answers)
"is" operator behaves unexpectedly with integers
(11 answers)
Is there a difference between "==" and "is"?
(13 answers)
Is there any difference between "foo is None" and "foo == None"?
(12 answers)
Closed 2 years ago.
The is keyword in python is described like that:
is is used in Python for testing object identity. While the == operator is used to test if two variables are equal or not, is is used to test if the two variables refer to the same object.
It returns True if the objects are identical and False if not.
>>> True is True
True
>>> False is False
True
>>> None is None
True
We know that there is only one instance of True, False and None in Python, so they are identical.
>>> [] == []
True
>>> [] is []
False
>>> {} == {}
True
>>> {} is {}
False
An empty list or dictionary is equal to another empty one. But they are not identical objects as they are located separately in memory. This is because list and dictionary are mutable (value can be changed).
>>> '' == ''
True
>>> '' is ''
True
>>> () == ()
True
>>> () is ()
True
Unlike list and dictionary, string and tuple are immutable (value cannot be altered once defined). Hence, two equal string or tuple are identical as well. They refer to the same memory location.
Till now there is no problem. My issue is that I have two instances of two variables as string type
a = 'yasser'
b = 'yasser'
a is b
This code returns True
while
a = 'yasser!'
b = 'yasser!'
a is b
This returns False althought these are of string types. Any explanation..?
The 'is' keyword evaluates to true if the true arguments are from the same object. In the cases you had above, all of the ones that evaluate to true are from the same object, however, while those two strings are identical, they are not the same object. You can read more about it here.

Why does this str strict comparison fail in Python? [duplicate]

This question already has answers here:
Why does comparing strings using either '==' or 'is' sometimes produce a different result?
(15 answers)
Closed 8 years ago.
I have this code in a decorator:
is_local_valid = ['system_id', 'server_id', 'sensor_id']
local_params = [x for x in is_local_valid if x in kwargs.keys() and kwargs[x].lower() is 'local'] + [y for y in args if y.lower() is 'local']
if local_params == []:
raise AssertionError("Tried to access the database from a non connected profile")
I noticed that the is infix operator for comparing two strings returns False in this case, even when kwargs[x].lower() equals to local. The == operator does return True, though. Both are str, of course.
Any clue on what's going on?
The operators is and is not test for object identity:
x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value.
>>> id('local')
42745112
>>> a = {1: 'locAl'}
>>> id(a[1].lower())
53363408
They are not the same object
a is b determines whether two names a and b reference the same object (i.e. id(a) == id(b)). a == b determines whether they have equal values. It is rarely a good idea to compare strings with is; use == instead:
>>> "".join("hello")
'hello'
>>> "hello" is "".join("hello")
False
>>> "hello" == "".join("hello")
True
The only general case for comparison with is would be for None, e.g.:
if a is None:

Why does string > int evaluate to True? [duplicate]

This question already has answers here:
How does Python 2 compare string and int? Why do lists compare as greater than numbers, and tuples greater than lists?
(2 answers)
Closed 9 years ago.
How come a check of string > int evaluates to True?
>>> strver = "1"
>>> ver = 1
>>> strver > ver
True
>>> strVer2 = "whaat"
>>> strVer2 > ver
True
Did some more experimenting:
>>> ver3 = 0
>>> strVer2 > ver3
True
I think there should be an error when trying to compare but it seems like nothing is built to handle such an error, or assert should be used but that can be dangerous if python code is being run with -O flag!
Source: How does Python compare string and int?, which in turn quotes the CPython manual:
CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don’t support proper comparison are ordered by their address.
From the SO answer:
When you order two incompatible types where neither is numeric, they are ordered by the alphabetical order of their typenames:
>>> [1, 2] > 'foo' # 'list' < 'str'
False
>>> (1, 2) > 'foo' # 'tuple' > 'str'
True
>>> class Foo(object): pass
>>> class Bar(object): pass
>>> Bar() < Foo()
True
...so, it's because 's' comes after 'i' in the alphabet! Luckily, though, this slightly odd behavior has been "fixed" in the implementation of Python 3.x:
In Python 3.x the behaviour has been changed so that attempting to order an integer and a string will raise an error:
Seems to follow the principle of least astonishment a little better now.

How does python evaluate "is" expressions? [duplicate]

This question already has answers here:
"is" operator behaves unexpectedly with integers
(11 answers)
Closed 9 years ago.
Erratic behavior of "is" expressions in python.
>>> 258 -1 is 257
False
And
>>> 258 -1 == 257
True
How is python evaluating "is" expression ? and why does it show it as false , eventhough it is true ?
Why is it happening only to certain set of numbers ?
2 - 1 is 1
True
works perfectly fine.
is is used for identity check, to check if both variables point to the same object,
while == is used for checking values.
From the docs:
The operators is and is not test for object identity: x is y is true
if and only if x and y are the same object. x is not y yields the
inverse truth value.
>>> id(1000-1) == id(999)
False
""" What is id?
id(object) -> integer
Return the identity of an object. This is guaranteed to be unique among
simultaneously existing objects. (Hint: it's the object's memory address.)
"""
>>> 1000-1 is 999
False
>>> 1000-1 == 999
True
>>> x = [1]
>>> y = x #now y and x both point to the same object
>>> y is x
True
>>> id(y) == id(x)
True
>>> x = [1]
>>> y = [1]
>>> x == y
True
>>> x is y
False
>>> id(x),id(y) #different IDs
(161420364, 161420012)
But some small integers(-5 to 256) and small strings are cached by Python: Why (0-6) is -6 = False?
#small strings
>>> x = "foo"
>>> y = "foo"
>>> x is y
True
>>> x == y
True
#huge string
>>> x = "foo"*1000
>>> y = "foo"*1000
>>> x is y
False
>>> x==y
True
is compares object identity and yields True only if both sides are the same object. For performance reasons, Python maintains a "cache" of small integers and reuses them, so all int(1) objects are the same object. In CPython, cached integers range from -5 to 255, but this is an implementation detail, so you should not rely on it. If you want to compare equality, use ==, not is.
The is operator checks for object identity: the object created by calling 258-1 is NOT the same object as the one created by 257. The == operator checks if the values of the compared objects are the same.
Try using help('is').
The Python is operator checks for object identity, not object value. The two integers must refer to the same actual object internally for is to return true.
This will return true for "small" integers due to an internal cache maintained by Python, but two numbers with the same value will not return true if compared with is in general.

Python - comparing long/integer values with == and is [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Python “is” operator behaves unexpectedly with integers
Ran into something odd last night where doing
if max_urls is 0:
max_urls = 10
would always return false... even when max_urls was 0.... it was getting assigned from the database. When I did a
print type(max_urls)
would return
<type 'long'> 0
which seemed right but it would always return false.
If I changed it to
if max_urls == 0:
max_urls = 10
then finally it would return true when it was 0. Why the difference between == and is?
== is a value comparison, is is an object identity (memory location) comparison. You will often see that comparisons like max_urls is 0 will give the intended result because small values are usually cached in Python, but you always want to be using == instead of is when checking equality because this behavior cannot be relied upon.
Here is a brief example illustrating this:
>>> a = 0
>>> (a == 0, a is 0)
(True, True)
>>> a = 1000
>>> (a == 1000, a is 1000)
(True, False)
The is operator checks that two references point to the same object. You are testing if long(0) is the same object as int(0), and the answer is no. This will be crystal clear if you print their object ids:
>>> max_urls = long(0)
>>> id(max_urls)
335952
>>> id(0)
8402324
== on the other hand checks that two values are equivalent, even if they are not the exact same object. For instance:
>>> a = 777
>>> b = 777
>>> a is b
False
>>> a == b
True
>>> id(a)
8404568
>>> id(b)
8404640
Note: It is important that I used 777 and not a smaller number like 1 or 2. Quoting from the Python manual:
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.

Categories