negative numbers are not equal...

Discussion in 'Python' started by ariel ledesma, Aug 14, 2008.

  1. hello guys

    i just ran into this when comparing negative numbers, they start
    returning False from -6 down, but only when comparing with 'is'
    True

    i read that 'is' compares if they are really the same object, but i
    don't that's it because then why does -5 return True?
    of course i could only use == to compare, but still, what am i missing here?
    thanks in advance

    ariel
     
    ariel ledesma, Aug 14, 2008
    #1
    1. Advertisements

  2. ariel ledesma

    Josh English Guest

    strange, I get the same thing.

    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.

    so:
    True

    It is odd behaviour, but I would stick to '==' when comparing numeric
    values
     
    Josh English, Aug 14, 2008
    #2
    1. Advertisements

  3. ariel ledesma

    Dan Lenski Guest

    They also return False for positive numbers > 256. Try this:
    [-10, -9, -8, -7, -6, 257, 258, 259]

    There is a good explanation for this: the "is" operator checks for object
    identity, not equality. Basically "a is m" asks, does the variable name
    "a" reference the same memory location as the variable name "m"?

    For integers in the range of -5<=x<=256, Python pre-caches all of these
    values, and whenever a variable takes on one of those values, it uses the
    cached value. This is an optimization: it prevents the need to allocate
    a new Python object for these very very common small integer values.

    For integer literals outside this range, a new Python object gets created
    when they are assigned to variables, so a=500 followed by m=500 will
    create new objects.

    The "is" operator just shows the effect of this caching. It's
    unimportant for real code since you never care whether two numeric
    variables refer to the same object (only important for complex data
    structures where their storage may overlap)... only whether they are
    equal or not.

    Dan Lenski

    (PS- The small integer pre-caching is described somewhere in the C API
    docs.)
     
    Dan Lenski, Aug 15, 2008
    #3
  4. castironpi a écrit :
    (snip)
    When I want to test objects identity. An idenity test is an identity
    test is an identity test is an....
    Because there's a need for it.
     
    Bruno Desthuilliers, Aug 15, 2008
    #4
  5. ariel ledesma

    castironpi Guest

    It would be nice to put together a really canonical case of the use of
    the 'is' comparison. FTSOA for the sake of argument, when do you use
    it? Why is it even in the language?

    If you're iterating over a list,

    flagA= object()
    flagB= object()
    flagC= -10
    listA= [ objectA, objectB, flagA, objectC, flagB, -10, objectD ]
    flags= [ listA, listB, listC ]
    for iA in listA:
    for flag in flags:
    if iA is flag:
    handle( iA )

    This case actually misses handleC(). The solution is that the
    function that is returning '-10' cannot return -10, it has to return
    flagC. This can cause difficulties in cases when you're doing
    operations on flags. Worse, if flagC is nested somewhere, say
    moduleA.classB.flagC, you still have to work with that, not its value.
     
    castironpi, Aug 15, 2008
    #5
  6. do you *ever* make any sense at all?

    </F>
     
    Fredrik Lundh, Aug 15, 2008
    #6
  7. Terry Reedy a écrit :
    make it four.
    Warning (to any python newbie reading this): x is True is *very*
    different from x == True. IOW ;: don't use 'is' with True and False
    unless you know *exactly* what you're doing.
    4. Anywhere you want to test identity.
     
    Bruno Desthuilliers, Aug 15, 2008
    #7
  8. ariel ledesma

    Mel Guest

    My poster child use case is in a MUDD game. For instance, the player
    represented by `this_player` has picked up the yoghurt. We notify the
    other players using code that boils down to:

    for person in this_room.inhabitants:
    if person is not this_player:
    person.notify ('%s has picked up the %s.'
    % (this_player.name, 'yoghurt'))

    The `is` test avoids telling this_player something he already knows.
    Perhaps the code could be written to make an equality test work, but then
    again, perhaps the game could have a much more interesting use for equality
    between persons.

    Mel.
     
    Mel, Aug 15, 2008
    #8
  9. ariel ledesma

    Terry Reedy Guest

    Excellent example. There are three uses for 'is'.
    1. Minor optimization of comparison with None, True, False.
    2. Testing the implementation: 'a=1;b=1;a is b' *should* be True, while
    'a=257;b=257;a is b' *should* be False. The CPython test suite has
    tests like this.
    3. Comparision of user class objects where identify is important.
    Objects representing people is certainly such a case ;-).

    tjr
     
    Terry Reedy, Aug 15, 2008
    #9
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.