On Tue, 02 May 2006 17:15:05 +0000, John Salerno wrote: > Basically W, X, Y and Z are propositions > that are either true or false, and the puzzle lists a few statements > such as "Exactly one of X, Y and Z is true", and I'm trying to work out > a little algorithm that might test for this kind of stuff.
Okay. You don't need to worry about the "is" tests at all. Python always represents the value "True" with a reference to a True object, and likewise "False" is a reference to a False object. To save memory, Python has just one of each object, so: a = False b = False a is b # this will always be true As some other posters showed by example, but didn't really explain, Python will *sometimes* but not always reuse integer objects. For common integer values such as 0 and 1, Python will reuse the objects; for uncommon (larger) values, Python usually won't. So: a = 12345 b = 12345 a is b # probably not true a = 0 b = 0 a is b # always true A key point is that you never really "assign a value to a variable". What you really do is "bind an object reference to a name". The long, simultaneous assignment form binds the same object reference to multiple variables: a = b = c = d = 12345 a is b # always true But as soon as you reassign any of the variables you will rebind the name to some other object reference: a += 1 a is b # definitely false a = 12345 a is b # probably false Python *could* notice that it already has an integer object with the value 12345, and rebind the name a with a reference to it. But in practice Python will probably just create a new integer object with value 12345, since the Python interpreter doesn't spend large amounts of time looking through its collection of objects to find ones that can be reused. Python also has exactly one "None" object, and always uses references to it whenever you reference None in your code. This is why it is preferred Python style to test for None with an "is" test: a is None Anyway, the major point I want you to take away from all this: it doesn't matter whether the "is" test succeeds or fails, if all you care about is the *value* of a variable. Python reuses object references to save memory, because this doesn't affect expressions that only care about the *value*. Your logic tests only care about True vs. False; they don't care about the underlying implementation of how True and False are expressed. > Another thing I'm trying to do is write a function that tests to see if > a list contains exactly one true item, and the rest are false (obviously > this would have to be a list of boolean values, I guess). I'm sure this > isn't a handy utility, but I enjoy figuring out how to implement it. This is a simple problem. I suggest you loop over the list and simply count how many values are false, and how many are true. I just wrote and tested this function in about a minute. The list doesn't have to be a list of booleans, actually. Python has a set of rules for evaluating other values as booleans: if 0: pass # never executed; 0 always false if "": pass # never executed; 0-length string always false if []: pass # never executed; 0-length list always false So, don't test to see if something is equal to True or False: if 0 == False: pass # never executed; False and 0 do not directly compare You *could* do this, but I don't really recommend it: if bool(0) == False: pass # always executed Do this: if not 0: pass # always executed if 1: pass # always executed To convert a random value into a boolean value, you could use either "bool()" or you could use "not not": a = not not 0 b = bool(0) "not not" will work on older versions of Python that didn't have an explicit boolean type; "not 0" would return 1 in that case. "bool()" will work in Python 2.2 and newer. -- Steve R. Hastings "Vita est" [EMAIL PROTECTED] http://www.blarg.net/~steveha -- http://mail.python.org/mailman/listinfo/python-list