0

I'm pretty new to python. And I have a question.

 def set_man(self, new_pos):
    if new_pos is 'left' or 'right' or 'boat':
        self.man = new_pos
        return True
    else:
        return False

will this work? Or do i need to call if new_pos for each or?

Christian Moen
  • 1,253
  • 2
  • 17
  • 31
  • 4
    No. Try `if new_pos in ('left','right','boat'):`. – Sci Prog Mar 11 '16 at 23:19
  • Wow, thank you. That was pretty quick! – Christian Moen Mar 11 '16 at 23:20
  • 1
    That won't work for two reasons. One will be displayed by people with better dupe skills than I. The other is that `is` tests to see if one object is the same object as another. That is, it gives `True` only if they have the same place in memory. What you want, though, is to see if they are equivalent. Do `if new_pos in ("left", "right", "boat"):` – zondo Mar 11 '16 at 23:21
  • Yeah, so i know. That is basicly the same as using == to check two strings in java? – Christian Moen Mar 11 '16 at 23:22
  • 2
    The first reason that I mentioned is demonstrated in [this](https://stackoverflow.com/questions/15112125/how-do-i-test-one-variable-against-multiple-values) post. – zondo Mar 11 '16 at 23:24
  • 1
    This is a double dupe and I accidentally retracted... :) [dupe1](http://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python) [dupe2](http://stackoverflow.com/questions/15112125/how-do-i-test-one-variable-against-multiple-values) – timgeb Mar 11 '16 at 23:28
  • "That is basicly the same as using == to check two strings in java" No it's not. Was that your question? It doesn't look like that. – Stop harming Monica Mar 11 '16 at 23:40
  • @timgeb it's actually more a dupe of the dupe2 link you provided, as his question really is about checking one value against several others. I just voted to close it as dupe. – zmo Mar 11 '16 at 23:51

2 Answers2

4

will this work?

no it won't, because what you wrote is actually:

  • new_pos is "left"id(new_pos) == id("left") → boolean value X
  • 'right' alone → bool('right') → always True
  • 'boat' alone → bool('boat') → always True

when you evaluate that expression you get: X or True or True which always evaluates to True. So as a result, whatever new_pos is your function will always return True and assign new_pos to self.man.

Or do i need to call if new_pos for each or?

well that's a way to do it:

if new_pos is 'left' or new_pos is 'right' or new_pos is 'boat':

but that's a bit verbose, and not very elegant. A better way to write it down is to ask whether new_pos is in the tuple ('left', 'right', 'boat'):

if new_pos in ('left', 'right', 'boat'):

Nota Bene: even though I prefer to use is when working with strings (as it often makes beautiful sentences like if user_input is "yes", be aware that this is an exceptional behaviour of the is operator.

The is operator is being used to match whether two instances are the same instance (i.e. the same object in memory), whereas the == operator checks whether the value of both instances are the same, and the == operator can be defined by the developer using __eq__ for custom behaviours.

This is why the is operator is called the 'identity' operator, whereas the == operator is the equality operator. Given that the id() operator gives an unique id for an instance: you can translate a is b into id(a) == id(b). Have a read of this QA for more on that.

Community
  • 1
  • 1
zmo
  • 24,463
  • 4
  • 54
  • 90
  • I don't think adding `is not None` to the `right` and `boat` checks is appropriate. Empty strings and containers and the zero values of various numeric types are also "falsey" in Python, not only `None`. Maybe use `bool('left')` instead of `'left' is not None`? – Blckknght Mar 11 '16 at 23:54
  • oh, what I wrote was just the meaning in full english, not in python. Which is why I used the backticks! But you're right, let me detail more what is really being done. – zmo Mar 12 '16 at 00:12
  • edited, hope you'll like it better that way ☺ – zmo Mar 12 '16 at 00:14
0

If you want to learn the topic, see this thread

If you just want your code to work as it is, use it like that:

 def set_man(self, new_pos):
    if new_pos is 'left' or new_pos is 'right' or new_pos is 'boat':
        self.man = new_pos
        return True
    else:
        return False
Community
  • 1
  • 1