2

In my project I have used or but in some cases it works and in some cases it fails me.. I cant understand Why?

if (a or b) is not True:
    # This works for me


if (a or b) == "Django" and (c or d) == "Pyramid":
    # This fails me everytime
mechanical_meat
  • 163,903
  • 24
  • 228
  • 223
manjusha
  • 21
  • 1

3 Answers3

3

a or b evaluates to a if a evaluates to True. If a evaluates to False, a or b evaluates to b.

For instance:

[] or 'a' #evaluates to 'a'
'a' or None #evaluates to 'a'
[] or None #evaluates to None
None or [] #evaluates to []

Your (a or b) == 'Django' should be a == 'Django' or b == 'Django'.

('Django' or 'Nomatterwhat') == 'Django' #True
([] or 'Django') == 'Django' #True
('Mono' or 'Django') == 'Django' #False

Having said the theoretical part, try running this little program, to see how or and and work (especially the lazy evaluation part):

def x():
    print('X')
    return False

def y():
    print('Y')
    return True

print ('-' * 20)
x() or y()
print ('-' * 20)
y() or x()
print ('-' * 20)
x() and y()
print ('-' * 20)
y() and x()
Hyperboreus
  • 31,997
  • 9
  • 47
  • 87
1

if a == 'Django' or b == 'Django':

linbo
  • 2,393
  • 3
  • 22
  • 45
0

Your parentheses are in the wrong place. (a or b) will always return the first of a or b which evaluates to True, so:

>>> a = "Django"
>>> b = "Pyramid"
>>> (a or b)
"Django"
>>> (a or b) == "Django"
True

but

>>> (b or a)
"Pyramid"
>>> (b or a) == "Django"
False

What you actually want to write is:

>>> a == "Django" or b == "Django"
True

However, an alternative way of writing it which may be better in many cases is:

if "Django" in (a, b) or "Pyramid" in (a, b):
    ...

Or, if there are many options:

if set([a, b, c, ...]) & set(["Django", "Pyramid", ...]):
    ...
aquavitae
  • 17,414
  • 11
  • 63
  • 106
  • In which version of python and in which implementation resolves `'Django' or 'Pyramid'` to `True`? And even more interesting: Why should `('Django' or 'Pyramid') == 'Django'` be `False`? – Hyperboreus Dec 04 '13 at 05:56
  • I tried it in both 3.3 and 2.7 (cython) and in both versions I get completely different results as the ones you posted. – Hyperboreus Dec 04 '13 at 06:00
  • Sorry - typo! It should be "Django", I'll correct the answer and make the meaning clearer – aquavitae Dec 04 '13 at 06:05
  • Y if "Django" in (a, b) or "Pyramid" in (a, b): works... Is it a good practise to use this?? – manjusha Dec 04 '13 at 06:10
  • @manjusha Nothing wrong about it. Also see the documentation for `all` and `any`. – Hyperboreus Dec 04 '13 at 06:11