Q:

Given 2 int values, return True if one is negative and other is positive

def logical_xor(a, b): # for example, -1 and 1
    print (a < 0) # evaluates to True
    print (b < 0) # evaluates to False
    print (a < 0 ! = b < 0) # EVALUATES TO FALSE!  why???  it's True ! = False
    return (a < 0 ! = b < 0) # returns False when it should return True

print ( logical_xor(-1, 1) ) # returns FALSE! 

# now for clarification

print ( True ! = False) # PRINTS TRUE! 

Could someone explain what is happening?  I'm trying to make a one liner:
lambda a, b: (a < 0 ! = b < 0)

A:

All comparison operators in Python have the same precedence.  In addition, Python does chained comparisons.  Thus, 
(a < 0 ! = b < 0)

breaks down as:
(a < 0) and (0 ! = b) and (b < 0)

If any one of these is false, the total result of the expression will be False.  
What you want to do is evaluate each condition separately, like so:
(a < 0) ! = (b < 0)

Other variants, from comments:
(a < 0) is not (b < 0) # True and False are singletons so identity-comparison works

(a < 0) ^ (b < 0) # bitwise-xor does too, as long as both sides are boolean

(a ^ b < 0) # or you could directly bitwise-xor the integers; 
            # the sign bit will only be set if your condition holds
            # this one fails when you mix ints and floats though

(a * b < 0) # perhaps most straightforward, just multiply them and check the sign

A:

Your code doesn't work as intended because ! = takes higher precedence than a < 0 and b < 0.  As itzmeontv suggests in his answer, you can simply decide the precedence yourself by surrounding logical components with parentheses:
(a < 0) ! = (b < 0)

Your code attempts to evaluate a < (0 ! = b) < 0
[EDIT]
As tzaman rightly points out, the operators have the same precedence, but your code is attempting to evaluate (a < 0) and (0 ! = b) and (b < 0).  Surrounding your logical components with parentheses will resolve this:
(a < 0) ! = (b < 0)

Operator precedence: https://docs.python.org/3/reference/expressions.html#operator-precedence
Comparisons (i.a.  chaining): https://docs.python.org/3/reference/expressions.html#not-in

A:

You can use this
return (a < 0) ! = (b < 0)

Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false). 

So it becomes
(a < 0) and (0 ! = b) and (b < 0)

See https://docs.python.org/3/reference/expressions.html#not-in

