Strict comparison

后端 未结 5 1811
再見小時候
再見小時候 2021-01-17 11:43

In javascript, there are strict comparison operators op1 === op2 and op1 !== op2 that will compare both type and value. Is there a pythonic way of

5条回答
  •  北海茫月
    2021-01-17 12:08

    Python's equal comparator is strict except for when comparing 1 to True, and 0 to False, and it doesn't matter if the value for 1 or 0 is of type float, decimal.Decimal, or long. Zero of any numeric type, for example, 0, 0L, 0.0, 0j is always False. (Note that anything else cast to a bool is True. See Truth Value Testing in Python.) 1 of any type except complex (1L, 1.0, 1) is always True.

    In Python:

    0 == '0'  # False
    0 == '0' and type(0) == type('0')  # False, compare short circuits 
    0 == ''  # False
    0 == '' and type(0) == type('')  # False, compare short circuits 
    
    1 == True and type(1) == type(True)  # False, makes a difference here
    1 == True  # True, also true if 1 was 1.00, etc..
    0 == False  # True
    False == None  # False
    0 == bool(None)  # True
    

    When the first comparison returns False, the second one is not evaluated, hence it short circuits because 0 and anything else is 0. This is unnecessary though, it would only apply to when comparing 1 to True in line 6.

    In JavaScript:

    0 == '0'  //true
    0 === '0'  //false
    0 == ''  //true
    0 === '0' //false
    
    1 === true //false
    1 == true //true
    0 == false //true
    false == null //false
    0 == !!(null) //true
    

    So the closest thing to the JavaScript === in Python is:

    a == b and type(a) == type(b)
    

    But only would need to be used in the case of a boolean comparison to 1 or 0, which is unlikely. If you expect a value to be either a numeric or a boolean, you might want to fix your code. A rookie mistake is to have something like this occur:

    a = 0.0  # a valid value, lets assume it comes from a source that can also return None and we have no control over that.
    
    # Should be:
    # if a not None:
    if a: # a is cast to bool, bool(0.0) is False
        print "do something here..."
    

    Just to clear up some confusion, its good to be aware of Python's is operator. Python has a is operator which returns True if both sides of the is are bound to the same object, otherwise it returns False. When using string literals, the lifetime of the objects is only for the instance of the statement. So performing is on string literals is safe since if they are the same, they are assigned to the same object. This also applies to other immutable types like bool, and all number types:

    0 is '0'  # False
    0 is False  # False
    0 is 0  # True
    

    This is not guaranteed to work when comparing two variables or a variable and a literal.

    When you create two empty lists you get two different objects, so is returns False:

    x = []
    y = []
    x is y  # False
    

    But in this case, these variables reference the same list, and will continue to do so until they are re-assigned, or a deep copy is made of one from the other:

    x = y = []
    x is y  # True
    x.append(1)
    x is y  # True
    x = [1, ]
    x is y  # False, even though the value is same
    

    The is operator is comparing the identities of the objects, it is performing the following:

    id('0') == id(0)
    

    So if both objects reference the same memory, they reference the same object and therefore must be the same.

    Its a good idea to avoid is to make strict comparisons unless you want to check if both objects are referencing the same memory.

    As Simon's answer states, Python's philosophy on equality differs from JavaScript's and there really is no need for a strict equality comparator. Python's equality comparator is not loose like JavaScripts == but at the same time its not exactly the same as ===.

    You should be okay with Python's equality comparator as long as its clear to you that zero of any numeric type (0, 0L, 0.0, 0j) is always equal to False and 1 of any numeric type except complex numbers (1, 1L, 1.0) is True.

提交回复
热议问题