Strange Python behavior from inappropriate usage of 'is not' comparison?

后端 未结 5 806
南方客
南方客 2021-01-22 15:12

I (incorrectly?) used \'is not\' in a comparison and found this curious behavior:

>>> a = 256
>>> b = int(\'256\')
>>> c = 300
>>         


        
相关标签:
5条回答
  • 2021-01-22 15:53

    For small numbers, Python is reusing the object instances, but for larger numbers, it creates new instances for them.

    See this:

    >>> a=256
    >>> b=int('256')
    >>> c=300       
    >>> d=int('300')
    
    >>> id(a)
    158013588
    >>> id(b)
    158013588
    >>> id(c)
    158151472
    >>> id(d)
    158151436
    

    which is exactly why a is b, but c isn't d.

    0 讨论(0)
  • 2021-01-22 15:56

    "is" is not a check of equality of value, but a check that two variables point to the same instance of an object.

    ints and strings are confusing for this as is and == can happen to give the same result due to how the internals of the language work.

    0 讨论(0)
  • 2021-01-22 16:01

    For more understanding why this occurs take a look to Python-2.6.5/Objects/intobject.c:78:small_ints array and Python-2.6.5/Objects/intobject.c:1292:_PyInt_Init function in python sources.

    Also similar thing occurs with lists:

    
    >>> a = [12]
    >>> id_a = id(a)
    >>> del(a)
    >>> id([1,2,34]) == id_a
    True
    >>> 
    

    Removed lists are not destroyed. They are reused

    0 讨论(0)
  • 2021-01-22 16:03

    Don't use is [not] to compare integers; use == and != instead. Even though is works in current CPython for small numbers due to an optimization, it's unreliable and semantically wrong. The syntax itself is valid, but the benefits of a warning (which would have to be checked on every use of is and could be problematic with subclasses of int) are presumably not worth the trouble.

    This is covered elsewhere on SO, but I didn't find it just now.

    0 讨论(0)
  • 2021-01-22 16:12

    Int is an object in python, and python caches small integer between [-5,256] by default, so where you use int in [-5,256], they are identical.

    a = 256
    b = 256
    
    a is b # True
    

    If you declare two integers not in [-5,256], python will create two objects which are not the same(though they have the same value).

    a = 257
    b = 257
    
    a is b # False
    

    In your case, using != instead to compare the value is the right way.

    a = 257
    b = 257
    
    a != b # False
    
    0 讨论(0)
提交回复
热议问题