Re: question about True values
On 2006-10-29, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > On Sun, 29 Oct 2006 00:31:23 -0700, Carl Banks wrote: > > That's why (for example) Python allows + to operate on lists, or strings, > or floats That was IMO a mistake. There are types for which concatenation as well as addition are meaningfull operators. By using the "+" for both these operations, writing such a class becomes awkward in Python because you have to stray away from Python idiom for one of the two operations. Should Python have chosen the "_" character for concatenating writing amnd working with such a class would have looked more natural. > -- but that doesn't imply that you can add a list to a float, > or that the same code will operate happily on both lists and floats. You, > the developer, don't need to care what data types you are adding, you just > use the same syntax: a+b. Of course the developer needs to care. It's not because a+b will give a result that the result will also be meaningfull. It is not because a class has defined the operators "+", "-", "/", "*" it will give a meaningfull result if you throw a matrix of instances into procdure that solves equations. > The objects themselves know what addition > means to themselves. In practice, string addition threatens to be so > inefficient that you might wish to avoid doing it, but as a general > principle, Python idioms and syntax are as type-independent as possible. Which isn't necesarrily a good thing. I think there is even a warning somewhere against too easily overloading the arithmetic operators for operations that don't act at all as such operators. I think they should have thought of that before using "+" for concatenation. > That's why obj[index] works whether you are getting or setting or deleting > an item, whether it is a sequence or a mapping or a custom class. As much > as possible, you don't need to know what the object is to know what syntax > to use. The idiom for item-access should always be obj[index], not > obj[index] for some types, obj.get(index) for some others, and > getitem(obj, index) for the rest. > > (Custom classes are, of course, free to break these guidelines, just as > the numpy developers were free to have __nonzero__ raise an exception. One > hopes they have good reasons for doing so.) > > And that's why Python not only allows but prefers "if any_object_at_all:" > over type-dependent tricks. The *object itself* is supposed to know > whether it is equivalent to true or false But the objects idea of true and false may not be the most usefull distinction the programmer wants to make. Look at the following example: if container: Prepare() Treat(container) Now Treat will throw an exception if container is not enough list like. But that exception will be throw after Prepare has done useless work in this case. If I replace "if container" with "if len(container)" the exception will be thrown earlier. So using "if len(container)" gives more usefull information than a simple "if container". > (or, in rare cases like numpy > arrays, raise an exception if truth-testing doesn't mean anything for the > type). You, the developer, are not supposed to spend your time wondering > how to recognise if the object is equivalent to false, you just ask the > object. > > If some well-meaning person argued that the correct way to test for a > numeric value of zero/non-zero was like this: > > if x*2 != x: > # x must be non-zero > > you'd fall down laughing (at least, I hope you'd fall down laughing). Yes, > such a test works, but you'd be crazy to do such unnecessary work if all > you want to know if x was nonzero. (And beware of floating point rounding: > what if x is tiny?) > > And then someone passes a class that implements infinity or the alephs to > this function (that could simply mean an INF float on a platform that > supports the IE standard) and the code wrongly decides that INF is zero. > Oops. > > "if x == 0:" is better, but still not good enough, because you're > still making assumptions about the data type. What if it is a numeric type > that works with interval arithmetic? You don't know what the right way to > test for a False interval is -- but the interval class itself will know. But you have no idea that the interval of "False" will guide you to the right branch. And inteval class might treat all zero length intervals as False or it could have a special empty interval which would be the only False interval. Both could be argued for, but you would want to know which before you would rely on "if some_interval:" to guide you to the right branch. > And that's the point -- you're making unnecessary assumptions about the > data, *and* doing unnecessary calculations based on those assumptions. At > best, you're wasting your time. At worst, you're introducing bugs. You have to make assumptions anyway. And your kind of code could introduce bugs just the same. > It isn't often that I make an appeal to authority, but this is one of >
Re: question about True values
Steven D'Aprano wrote: > It isn't often that I make an appeal to authority, but this is one of > them. No offense, but when it comes to language design its a brave or > foolish programmer who bucks the language idioms that Guido chose. Well, it's pretty clear you consider some abstact notion of unity of style more important than practical considerations of how your data is used. In that case you might as well just go with what the authority tells you to. (And hope that your users don't do much numerical stuff.) Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Sun, 29 Oct 2006 00:31:23 -0700, Carl Banks wrote: > Steven D'Aprano wrote: >> Carl Banks: >> > Overall, your objections don't really apply, since you're arguing what >> > ought to be whereas my argument is pragmatic. Practically speaking, in >> > realistic situations, "if len(a)>0" will work for a wider range of types >> > than "if a:". >> >> Well, that's a quantitative claim you're making there. Have you >> actually gone through, say, the built in types and checked how many >> have a length versus how many work in a truth-context? > > No, and it's irrelevant to my argument. And yet you not only made the claim in the first place, but you also spend a good half or three quarters of your response justifying your claim. You obviously didn't think it was irrelevant when you first made the claim, and you clearly still don't think it was irrelevant now that you've spent time checking an arbitrary set of types. Either way, you're still wrong. "if a:" will work with EVERY TYPE except those few (the only one?) like numpy arrays which deliberately raise an exception because they don't make sense in a Boolean context. (And even then, arguably numpy is doing the wrong thing: the Pythonic behaviour would be for numpy arrays to all be True.) "if len(a)>0:" can only work with types that have lengths. It is a logical necessity that the number of types that have lengths must be no bigger than the number of types in total, numpy arrays notwithstanding. > For some reason, people seem to think it's absolutely wonderful that > you can write "if X:" somewhere, and that this "works" whether X is a > list or an int or any other object, as if "working" for both ints and > lists was actually useful. > > Well, it's not. > > You see, presumably you have to do something with X. And in realistic > code, there's not a lot of stuff you can do with that works for both > container types like lists and dict, and atomic types like ints and > floats. Who cares whether or not your function accepts mixed data types like lists and floats? Why do you think it matters whether the one function has to operate on both sequences and atomic types? What *does* matter is that, regardless of whether you are operating on sequences, mappings, numeric types, the same syntax works. That's why (for example) Python allows + to operate on lists, or strings, or floats -- but that doesn't imply that you can add a list to a float, or that the same code will operate happily on both lists and floats. You, the developer, don't need to care what data types you are adding, you just use the same syntax: a+b. The objects themselves know what addition means to themselves. In practice, string addition threatens to be so inefficient that you might wish to avoid doing it, but as a general principle, Python idioms and syntax are as type-independent as possible. That's why obj[index] works whether you are getting or setting or deleting an item, whether it is a sequence or a mapping or a custom class. As much as possible, you don't need to know what the object is to know what syntax to use. The idiom for item-access should always be obj[index], not obj[index] for some types, obj.get(index) for some others, and getitem(obj, index) for the rest. (Custom classes are, of course, free to break these guidelines, just as the numpy developers were free to have __nonzero__ raise an exception. One hopes they have good reasons for doing so.) And that's why Python not only allows but prefers "if any_object_at_all:" over type-dependent tricks. The *object itself* is supposed to know whether it is equivalent to true or false (or, in rare cases like numpy arrays, raise an exception if truth-testing doesn't mean anything for the type). You, the developer, are not supposed to spend your time wondering how to recognise if the object is equivalent to false, you just ask the object. If some well-meaning person argued that the correct way to test for a numeric value of zero/non-zero was like this: if x*2 != x: # x must be non-zero you'd fall down laughing (at least, I hope you'd fall down laughing). Yes, such a test works, but you'd be crazy to do such unnecessary work if all you want to know if x was nonzero. (And beware of floating point rounding: what if x is tiny?) And then someone passes a class that implements infinity or the alephs to this function (that could simply mean an INF float on a platform that supports the IE standard) and the code wrongly decides that INF is zero. Oops. "if x == 0:" is better, but still not good enough, because you're still making assumptions about the data type. What if it is a numeric type that works with interval arithmetic? You don't know what the right way to test for a False interval is -- but the interval class itself will know. And that's the point -- you're making unnecessary assumptions about the data, *and* doing unnecessary calculations based on those assumptions. At best, you're wasting your time. At worst, you're intr
Re: question about True values
Chetan wrote: >>> I am joining after some network downtime here, so I seem to have missed what >>> the real issue here is. At the risk of being completely irrelevant to the >>> discussion here, I think it doesn't seem to be just about something or >>> nothing - is None something or nothing? It seems to be neither: >> >> If is, of course, nothing. You may have misunderstood the semantics of the >> "and" and "or" operators. > > I have not. I just posted another message on the subject. All I am trying to > point out is that the "nothingness" evaluation does not occur at the level of > expressions. It is only when the expression is needed to make decisions about > control flow that this comes into picture. This is not correct. "and" and "or" involve truth (or "somethingness") evaluation, as you can see from this example: Python 2.5 (r25:51908, Sep 22 2006, 10:45:03) >>> class A: ... def __nonzero__(self): ... print "nonzero" ... return True ... >>> A() and 1 nonzero 1 >>> Georg -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Steven D'Aprano wrote: > Carl Banks: > > Overall, your objections don't really apply, since you're arguing what > > ought to be whereas my argument is pragmatic. Practically speaking, in > > realistic situations, "if len(a)>0" will work for a wider range of types > > than "if a:". > > Well, that's a quantitative claim you're making there. Have you > actually gone through, say, the built in types and checked how many > have a length versus how many work in a truth-context? No, and it's irrelevant to my argument. For some reason, people seem to think it's absolutely wonderful that you can write "if X:" somewhere, and that this "works" whether X is a list or an int or any other object, as if "working" for both ints and lists was actually useful. Well, it's not. You see, presumably you have to do something with X. And in realistic code, there's not a lot of stuff you can do with that works for both container types like lists and dict, and atomic types like ints and floats. All you could do is call generic object protocol stuff like id() or str(). There's some odd operations that can work for both a container and an atomic (addition); even so, it's rare that a given piece of code would actually be useful for both containers and atomics. (I mean, you could pass lists into a function such as the following, but would it be useful?) def binomial3(a,b,c,d): return a + 3*b + 3*c + d What I'm saying is, the fact that "if X:" "works" for almost any type is big ol' red herring. The only thing that really matters is if it works for types that _actually have some realistic overlapping uses_. So let's do your little exercise keeping that in mind. Let's look at realistic uses of containers. Suppose we have a function such as this: def f(X): if not X: return do_some_indexing(X[2],X[4]) We see that we subscript X. Now, you can't subscript an int, so if we're going to count number of types that support "if a:" versus the number that support "if len(a)>0", we're not going to consider ints. When deciding whether we should go with "if a:" or "if len(a)>0", we should only count types that support indexing. Objects that support indexing and work with "if a:": lists,tuples,dicts,strings,xrange,collections.deque,array.array Objects that support indexing and work with "if len(a)>0": lists,tuples,dicts,strings,xrange,collections.deque,array.array ... numpy arrays Another thing containers do a lot is iteration. Objects that support iteration and work with "if a:" lists,tuples,dicts,sets,strings,xrange,collections.deque,array.array Objects that support iteration and work with "if len(a)>0:" lists,tuples,dicts,sets,strings,xrange,collections.deque,array.array ... numpy arrays What can we conclude? If you're indexing or iterating, "if a:" and "if len(a)>0:" are equally successful for built-in types, but "if len(a)>0:" also works for numpy arrays. If your only measure of success is how many classes the emptiness tests works for, then "if len(a)>0:" wins. This is just an example; we haven't looked at all possible uses of containers. There will be a few cases where "if a:" works but "if len(a)>0:" doesn't. But it should be pretty clear where this is headed. So the question is: Do you want use "if len(a)>0:", so that in a lot of cases your code can also work if someone wants to use a popular third party package? Or do you want to use "if a:", so that in rare cases your code could also work with some builtin atomic types? Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Georg Brandl <[EMAIL PROTECTED]> writes: > Chetan wrote: >>> Steven D'Aprano wrote: >>> > On Sat, 28 Oct 2006 03:13:42 +0100, Steve Holden wrote: >>> > >>> >>> Finally, while True/False is a good mental mapping for numeric >>> >>> comparisons, >>> >>> take the following: >>> >>> >>> >>> >>> if "Cliff is a pillar of the open source community": >>> >>> print "thank you" >>> >>> else: >>> >>> print "bugger off" >>> >>> >>> >>> bugger off >>> >>> >>> >>> First off, even though nobody has called me on it, this example really >>> prints >>> "thank you", not "bugger off". I got confused in my cutting and pasting. >>> Sorry about that. >>> >>> >>> >>> Clearly this is not true. (Google Cliff/Dyer open source: only 11 >>> >>> hits.), >>> >>> but the string is *something* so the if block gets evaluated. >>> >>> >>> >> >>> if "The above example was bollocks": >>> >> ... print "You don't know what you are talking about" >>> >> ... else: >>> >> ... print "Sorry: of course you are perfectly correct" >>> >> ... >>> >> You don't know what you are talking about >>> > Cliff is making a point about semantics, and he's absolutely correct about >>> > it, although it is irrelevant since we're talking about two-value logic >>> > not semantics. >>> Cheers, >>> Cliff >> >> I am joining after some network downtime here, so I seem to have missed what >> the real issue here is. At the risk of being completely irrelevant to the >> discussion here, I think it doesn't seem to be just about something or >> nothing - is None something or nothing? It seems to be neither: > > If is, of course, nothing. You may have misunderstood the semantics of the > "and" and "or" operators. I have not. I just posted another message on the subject. All I am trying to point out is that the "nothingness" evaluation does not occur at the level of expressions. It is only when the expression is needed to make decisions about control flow that this comes into picture. > None > None and True > None or True >> True > None and False > None or False >> False > False or None > False and None >> False > True and None > True or None >> True > not None >> True > > x and y | x something | x nothing > --- > y something | y | x > y nothing | y | x > > x or y | x something | x nothing > --- > y something | x | y > y nothing | x | y > > > Georg -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Chetan wrote: >> Steven D'Aprano wrote: >> > On Sat, 28 Oct 2006 03:13:42 +0100, Steve Holden wrote: >> > >> >>> Finally, while True/False is a good mental mapping for numeric >> >>> comparisons, >> >>> take the following: >> >>> >> >>> >>> if "Cliff is a pillar of the open source community": >> >>> print "thank you" >> >>> else: >> >>> print "bugger off" >> >>> >> >>> bugger off >> >>> >> >> First off, even though nobody has called me on it, this example really prints >> "thank you", not "bugger off". I got confused in my cutting and pasting. >> Sorry about that. >> >> >> >>> Clearly this is not true. (Google Cliff/Dyer open source: only 11 >> >>> hits.), >> >>> but the string is *something* so the if block gets evaluated. >> >>> >> >> >>> if "The above example was bollocks": >> >> ... print "You don't know what you are talking about" >> >> ... else: >> >> ... print "Sorry: of course you are perfectly correct" >> >> ... >> >> You don't know what you are talking about >> > Cliff is making a point about semantics, and he's absolutely correct about >> > it, although it is irrelevant since we're talking about two-value logic >> > not semantics. >> Cheers, >> Cliff > > I am joining after some network downtime here, so I seem to have missed what > the real issue here is. At the risk of being completely irrelevant to the > discussion here, I think it doesn't seem to be just about something or > nothing - is None something or nothing? It seems to be neither: If is, of course, nothing. You may have misunderstood the semantics of the "and" and "or" operators. None None and True None or True > True None and False None or False > False False or None False and None > False True and None True or None > True not None > True x and y | x something | x nothing --- y something | y | x y nothing | y | x x or y | x something | x nothing --- y something | x | y y nothing | x | y Georg -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Gabriel Genellina <[EMAIL PROTECTED]> writes: > At Friday 27/10/2006 23:13, Steve Holden wrote: > >>J. Clifford Dyer wrote: >> > the one thing that Ms. Creighton points out that I can't get past is >> > that Python, even with its bool type, *still* evaluates somethingness >> > and nothingness, and True and False are just numbers with hats on. >> > >> > >>> True + 3 >> > 4 >> > >>> bool(True-1) >> > False >> > >>> bool(True-2) >> > True >> > >>> (10 > 5) + (10 < 5) >> > 1 >>Seems pretty clear to me that the situations you discuss above involve >>numeric coercions of a Boolean value. > > A "true" Boolean value should not be coerced into any other thing. True+1 is > as > meaningless as "A"+1, or even "1"+1. The fact is, bool is just an integer in > disguise. > I always regretted that Python just went mid-way moving onto a true Boolean > type; I'd prefer it to stay as it was before bool was introduced. > >> > Python is not evaluating the truth of the matter, but, as Ms. Creighton >> > would say, the "somethingness" of that which 10 > 5 evaluates to. (1 >> > aka True) >> > >> >>> type(10>5) >> >> >>> > bool.__mro__ > (, , ) > >>It does seem that there is a specific type associated with the result of >>a comparison, even though you would really like to to be "a number with >>a hat on". > > It *is* an integer with a hat on. > isinstance(True,int) > True This has focussed on the relational operators, which seem to produce a number with a hat on. However, logical operations do not do so. True and "This string" produces "This string", for example. This is hardly surprising, though. The way they are defined, booleans seem to be the syntactic sugar that some people like. Many of the projects that I have been associated with had such a define because the language (C) does not provide it. On the other hand, there are many who do just fine without them. For expressions used in control flow, if the expression somehow produces a 0 (False included) or None, the behavior is as if the expression is false. Confusion may arise because the way that answer is produced may not be immediately obvious. For constructs such as "if obj:" the answer depends on which methods the object has defined and what the state of the object is at the time, but this has nothing to do with whether the answer that was produced was strictly a boolean or not. Chetan > > > -- > Gabriel Genellina > Softlab SRL > > __ > Correo Yahoo! > Espacio para todos tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta > ya! - http://correo.yahoo.com.ar -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
> Steven D'Aprano wrote: > > On Sat, 28 Oct 2006 03:13:42 +0100, Steve Holden wrote: > > > >>> Finally, while True/False is a good mental mapping for numeric > >>> comparisons, > >>> take the following: > >>> > >>> >>> if "Cliff is a pillar of the open source community": > >>> print "thank you" > >>> else: > >>> print "bugger off" > >>> > >>> bugger off > >>> > > First off, even though nobody has called me on it, this example really prints > "thank you", not "bugger off". I got confused in my cutting and pasting. > Sorry about that. > > > >>> Clearly this is not true. (Google Cliff/Dyer open source: only 11 hits.), > >>> but the string is *something* so the if block gets evaluated. > >>> > >> >>> if "The above example was bollocks": > >> ... print "You don't know what you are talking about" > >> ... else: > >> ... print "Sorry: of course you are perfectly correct" > >> ... > >> You don't know what you are talking about > > Cliff is making a point about semantics, and he's absolutely correct about > > it, although it is irrelevant since we're talking about two-value logic > > not semantics. > Cheers, > Cliff I am joining after some network downtime here, so I seem to have missed what the real issue here is. At the risk of being completely irrelevant to the discussion here, I think it doesn't seem to be just about something or nothing - is None something or nothing? It seems to be neither: >>> None >>> None and True >>> None or True True >>> None and False >>> None or False False >>> False or None >>> False and None False >>> True and None >>> True or None True >>> not None True Chetan -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Sat, 28 Oct 2006 03:24:50 -0700, Carl Banks wrote: > Not all objects that have a state of emptiness consider emptiness to be > false. In which case they should define __nonzero__ appropriately. In which case, calling code that assumes that len(obj) is a substitute for truth-testing will do the wrong thing. >> > Whether you test with "if a:" or "if len(a)>0", some objects are >> > going to be denied. >> >> If a class doesn't define __nonzero__ or __len__, it should. > > No, it often shouldn't. Okay, I want to qualify my statement: if a class doesn't define __nonzero__ or __len__, *and doesn't want the default Python behaviour of all instances evaluating as True*, then they should. > A. It's not always desirable for empty to be false. Numpy defines a > bunch of numeric array types that raise an exception when __nonzero__ > (actually nb_nonzero in the C API) is called. This is the correct > behavior for numpy. It makes no sense for numpy arrays to be used in a > boolean context, but they certainly can be empty. And, appropriate to the class, numpy arrays raise an exception when __nonzero__ is called -- just as they should. > B. Sometimes it's impossible to determine the state of emptiness. For > example, iterators. Since Guido has ruled that the protocol is that all iterators are True, there is no need for __nonzero__ since the default behaviour does the job. [snip] >> Perhaps this behaviour has changed in version 2.5, if so, I'd like to >> hear the rationalisation before I declare it a mistake. > > You haven't been paying attention. > > Yes, this behavior has been changed in 2.5. The built-in iterators > always return True in 2.5. But even in 2.4, it was not true for > iterators in general: Yes, you are right. I was fooled by a coincidence. > At no point could you count on an iterator returning False for empty, > unless you'd made it yourself. Neither "if a:" nor "if len(a)>0" is a > valid test for an empty iterator. Correct. Guido's decision is that iterators are always "Something" (that is, True in a truth context) even if they are exhausted. >> > P.S. binary trees do have length: it's the number of nodes, just as >> > the number of keys is the length of a dict. >> >> I don't know what you were taught, but I was taught that binary trees >> have height and breadth. > > It doesn't really matter. dicts and sets don't have a length, either. > Or if they do, it's the length of the hash table, not the number of > entries. Weren't you taught that? But Python uses len() to get the > number of items in a container. Any Pythonic implementation of a binary > tree class would use len() to return the number of entries in it. > Anything that uses indexing ought to define len(), if it can. In the binary tree: tree --> A A.left --> B, A.right --> C what's tree[0]? Should it be A (preorder), or B (inorder) or C (postorder)? > Overall, your objections don't really apply, since you're arguing what > ought to be whereas my argument is pragmatic. Practically speaking, in > realistic situations, "if len(a)>0" will work for a wider range of types > than "if a:". Well, that's a quantitative claim you're making there. Have you actually gone through, say, the built in types and checked how many have a length versus how many work in a truth-context? >>> import types >>> if types: ... print "Modules work with bool" ... Modules work with bool >>> if len(types)>0: ... print "Modules work with len" ... Traceback (most recent call last): File "", line 1, in ? TypeError: len() of unsized object "if len(a)>0:" only works for objects that define __len__. "if a:" works for any object that doesn't go to the trouble of specifically prohibiting it, as numpy arrays deliberately do. That's the Python way, and it is a deliberate design. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Steven D'Aprano wrote: > On Sat, 28 Oct 2006 03:13:42 +0100, Steve Holden wrote: > >>> Finally, while True/False is a good mental mapping for numeric >>> comparisons, take the following: >>> >>> >>> if "Cliff is a pillar of the open source community": >>> print "thank you" >>> else: >>> print "bugger off" >>> >>> bugger off >>> First off, even though nobody has called me on it, this example really prints "thank you", not "bugger off". I got confused in my cutting and pasting. Sorry about that. >>> Clearly this is not true. (Google Cliff/Dyer open source: only 11 >>> hits.), but the string is *something* so the if block gets evaluated. >>> >> >>> if "The above example was bollocks": >> ... print "You don't know what you are talking about" >> ... else: >> ... print "Sorry: of course you are perfectly correct" >> ... >> You don't know what you are talking about > > Cliff is making a point about semantics, and he's absolutely correct about > it, although it is irrelevant since we're talking about two-value logic > not semantics. > > > > Thank you for the clarification Steven (D'Aprano). To a certain level, I agree that semantics are important. I hesitated about including that example in my post to begin with. However, my point, and hopefully I'll be able to make it more clearly now, was that true/false is a useful way to think regarding logical statements like x == 3, but that when you are dealing with strings, or more accurately strings that represent language, you really aren't talking about truth any more, because in that context, truth cannot be divorced from semantics--somethingness, on the other hand, can. Conceptually, you have to go through "'something' is true, and 'nothing' is false" before it makes sense. On the other hand, (to play devil's advocate for a moment), when you are dealing with comparison operators, you have to go through "true statements yield something and false statements yield nothing" before it makes sense, or rather "yield a nothing value." So either way you think about it, you have to, in some cases, mentally convert from truthiness to somethingness or vice versa. I don't find it as odious to mentally convert the comparison operators as I do the declarative statements. I don't think it's just a personal preference either, because that way your mental processes are in sync with the way python works. It evaluates if the statement is true and yields a something value, and a nothing value if it's false. You are working with the Tao of Python, if you'll forgive the analogy. However thinking in terms of truth and then saying that all statements that exist are true works, but runs counter to what is going on behind the scenes. Or maybe it doesn't, if everything's getting converted implicitly to bool anyway. Maybe it is just personal preference after all. But then bools are assigned "something" and "nothing" values This stuff is tricky, but I'm enjoying trying to wrap my mind around it, and appreciating the comments and critiques. Cheers, Cliff -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
J. Clifford Dyer wrote: > Georg Brandl wrote: >> J. Clifford Dyer wrote: >> >>> >>> (1 > 0) < 1 >>> False >>> >>> 1 > 0 < 1 >>> True >>> >>> 1 > (0 < 1) >>> False >>> >>> 10 > (0 < 1) >>> True >> >> I hope you know why this works the way it does. >> >> Georg > > Yes, I do understand why it works. I couldn't have crafted it if I > didn't, but my point is that the reason why it works is not explainable > if you believe that you are dealing with booleans. Okay, but you should have left off the second example, because it has nothing to do with the others. > It's only > explainable if you recognize that you are actually dealing with > integers, and specifically, 1 and 0. So the something/nothing dichotomy > combined with an understanding of what the comparison operation REALLY > does (yield a 1 or a 0) helps you understand where your result came > from, while thinking in terms of true/false will mislead you. That's true. The only sensible thing to do, if you had "real" booleans, for 1 > True, would be to raise an exception. Georg -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Georg Brandl wrote: > J. Clifford Dyer wrote: > >> >>> (1 > 0) < 1 >> False >> >>> 1 > 0 < 1 >> True >> >>> 1 > (0 < 1) >> False >> >>> 10 > (0 < 1) >> True > > I hope you know why this works the way it does. > > Georg Yes, I do understand why it works. I couldn't have crafted it if I didn't, but my point is that the reason why it works is not explainable if you believe that you are dealing with booleans. It's only explainable if you recognize that you are actually dealing with integers, and specifically, 1 and 0. So the something/nothing dichotomy combined with an understanding of what the comparison operation REALLY does (yield a 1 or a 0) helps you understand where your result came from, while thinking in terms of true/false will mislead you. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-28, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > On Fri, 27 Oct 2006 17:35:58 +, Antoon Pardon wrote: > >> On 2006-10-27, Steven D'Aprano <[EMAIL PROTECTED]> wrote: >> >> So >> it seems that python has generalised the len function to provide >> the number of elements in the container. > > Sure. But what about a container where the number of elements isn't > well-defined, e.g. iterators? I see you already discovered iterators won't help you here. > Or something like a binary tree, where > counting the number of items is relatively expensive, but telling whether > it is empty or not is cheaper than dirt? Counting the items in a binary tree and a dictionary are about equally expensive. I guess that in practice a count attribute will keep score. > Here's a real example: it can be expensive to count the number of files in > a directory -- on my PC, it takes almost a third of a second to count a > mere 15,000 files in a single directory. (There may be a more sensible > way of counting the number of files under Linux than ls | wc -l, but if > so I don't know it.) But why slog through 15,000 files if all you need to > know is if the directory is empty or not? As soon as you see one file, you > know it isn't empty. Stop counting! Who cares whether there is one file or > 15,000 files? I don't know why you consider this a real example. The only time I care whether a dictionary is empty or not is if I want to remove it and in that case it better to just try to remove the dictionary and catch the exception. Testing for emptyness or counting files in a directory isn't robust anyway. You never know whether or not some other process created a new file or deleted one between the time you tested and the moment >> I have written a Tree class(*). It can be used as a drop in replacement >> anywhere where a directory is used, as long as there is a full order >> relationship in the key domain. That tree class provides a __len__ >> method that will anser with the number of items in the tree just >> as a directory would and I see nothing wrong with that. > > And I'm happy for you. But imagine a container object that maps a URL to > some piece of data fetched from the Internet. Counting the size of the > Internet is infeasible -- even if you were willing to try, it could take > *weeks* of computation to determine! But one can certainly tell if there > is an Internet out there or not. Such an object would always be True, > unless you had lost network connectivity. Indeed and you could loose connectivity between your testing for it and making your first connection and your URL's turn bogus > My container object will work perfectly well with "if internet" but not > with "if len(internet) > 0". You could even iterate over it, sort > of, by following links from one site to another. And in what way exactly would this container object of yours be compatible with code that would expect a list like object? I guess not very much. > But why are you checking the length of a container before iterating over > it? If you are writing something like this: > > if len(container) != 0: > for item in container: > do_something() > > then just stop it! The same goes for if container: for iten in container: do_something() If your are writing the above you should stop it just the same. >> Of course I can't account for all possible ways someone wishes to >> write a class, but I don't see what is wrong with counting on >> the fact that an empty container has a length of zero. > > Because you shouldn't assume containers have well-defined lengths unless > you actually care about the length, and you shouldn't assume that length > of zero implies "nothing to see here" unless you *know* that this is the > case. I think these assumptions are equivallent with assuming it is a container. > You should leave defining empty up to the container class itself. > Otherwise, you might be right 99 times in a hundred, but that hundredth > time will bite you. Just as your assumption will bite you in case of numpy arrays. >> I can write a container class where the truth value of an object >> is independent of whether or not the object is empty and then >> the "if obj:" idiom will fail to provide true polymorphism too. > > A class that deliberate breaks the semantics of Python truth testing just > for the sake of breaking code really is a pathological case. Polymorphism > doesn't mean "will work with anything without exception". I find that your idea of what a container can lack also against the semantics of Python. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-28, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > On Fri, 27 Oct 2006 18:22:28 +, Antoon Pardon wrote: > And how do I express that a number has to be greater than 100 into a Nothing vs Something dichotomy? Declare all greater numbers as Something and the rest as Nothing? >>> >>> Well, would you declare numbers less than 100 False? >> >> No but the condition: x > 100, will map all numbers to >> either True or False. Can you provide a condition that will >> provide a mapping to Nothing and Something? Without >> artificially mapping False to Nothing and True to Something? > > A > B maps to max(0, A-B) > > or more verbosely, "Remove B items from A items, stopping when there are > no more items to remove. What is left over? Something or Nothing?" This mapping no longer works if you are not working with numbers. >>> A = [1,2] >>> B = [3] >>> A > B False >>> max(0, A - B) Traceback (most recent call last): File "", line 1, in ? TypeError: unsupported operand type(s) for -: 'list' and 'list' -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Sat, 28 Oct 2006 11:42:42 +0200, Marc 'BlackJack' Rintsch wrote: > In <[EMAIL PROTECTED]>, Steven > D'Aprano wrote: > >> On Fri, 27 Oct 2006 11:25:09 -0700, Carl Banks wrote: >> >>> Iterators do have overlapping uses with lists, but the "if a:" doesn't >>> work for them, so it's moot. >> >> Sure it works for iterators. >> > it = iter([0]) > bool(it) >> True > it.next() >> 0 > bool(it) >> False > > It works for *this* iterator. By accident. Blimey, you're right. That can't be good. In fact, it made a certain BDFL pretty mad: http://mail.python.org/pipermail/python-dev/2005-September/056594.html Okay, so all iterators are intentionally *supposed* to be True, always, even if they are exhausted. As Guido says, don't treat iterators as containers. Fair enough. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
J. Clifford Dyer wrote: > >>> (1 > 0) < 1 > False > >>> 1 > 0 < 1 > True > >>> 1 > (0 < 1) > False > >>> 10 > (0 < 1) > True I hope you know why this works the way it does. Georg -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Steven D'Aprano wrote: > On Fri, 27 Oct 2006 11:25:09 -0700, Carl Banks wrote: > > > Steven D'Aprano wrote: > >> But in this specific instance, I don't see any advantage to explicitly > >> testing the length of a list. Antoon might think that is sufficiently > >> polymorphic, but it isn't. He cares whether the object has zero _length_, > >> but for true polymorphism, he should be caring about whether the object is > >> _empty_. Not all empty objects have zero length, or even a length at all. > >> (E.g. binary trees.) > > > > Conversely, not all objects that have length consider zero-length to be > > false. > > Which is why truth-testing is defined by __nonzero__ with __len__ only the > fall-back, for convenience. Not all objects that have a state of emptiness consider emptiness to be false. > > Whether you test with "if a:" or "if len(a)>0", some objects > > are going to be denied. > > If a class doesn't define __nonzero__ or __len__, it should. No, it often shouldn't. A. It's not always desirable for empty to be false. Numpy defines a bunch of numeric array types that raise an exception when __nonzero__ (actually nb_nonzero in the C API) is called. This is the correct behavior for numpy. It makes no sense for numpy arrays to be used in a boolean context, but they certainly can be empty. B. Sometimes it's impossible to determine the state of emptiness. For example, iterators. > > Thing is, objects that don't have length have almost no overlapping > > uses with lists (i.e., you'd hardly ever write a function that could > > take an int or a list, unless you type check the argument or use only > > object protocol stuff like id and getattr, or pass it to another > > function that does the same). Iterators do have overlapping uses with > > lists, but the "if a:" doesn't work for them, so it's moot. > > Sure it works for iterators. > > >>> it = iter([0]) > >>> bool(it) > True > >>> it.next() > 0 > >>> bool(it) > False > > Perhaps this behaviour has changed in version 2.5, if so, I'd like to hear > the rationalisation before I declare it a mistake. You haven't been paying attention. Yes, this behavior has been changed in 2.5. The built-in iterators always return True in 2.5. But even in 2.4, it was not true for iterators in general: >>> a = [] >>> bool(x for x in a) True At no point could you count on an iterator returning False for empty, unless you'd made it yourself. Neither "if a:" nor "if len(a)>0" is a valid test for an empty iterator. > > P.S. binary trees do have length: it's the number of nodes, just as the > > number of keys is the length of a dict. > > I don't know what you were taught, but I was taught that binary trees have > height and breadth. It doesn't really matter. dicts and sets don't have a length, either. Or if they do, it's the length of the hash table, not the number of entries. Weren't you taught that? But Python uses len() to get the number of items in a container. Any Pythonic implementation of a binary tree class would use len() to return the number of entries in it. Anything that uses indexing ought to define len(), if it can. Overall, your objections don't really apply, since you're arguing what ought to be whereas my argument is pragmatic. Practically speaking, in realistic situations, "if len(a)>0" will work for a wider range of types than "if a:". Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
In <[EMAIL PROTECTED]>, Steven D'Aprano wrote: > On Fri, 27 Oct 2006 11:25:09 -0700, Carl Banks wrote: > >> Iterators do have overlapping uses with lists, but the "if a:" doesn't >> work for them, so it's moot. > > Sure it works for iterators. > it = iter([0]) bool(it) > True it.next() > 0 bool(it) > False It works for *this* iterator. By accident. Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Fri, 27 Oct 2006 11:25:09 -0700, Carl Banks wrote: > Steven D'Aprano wrote: >> But in this specific instance, I don't see any advantage to explicitly >> testing the length of a list. Antoon might think that is sufficiently >> polymorphic, but it isn't. He cares whether the object has zero _length_, >> but for true polymorphism, he should be caring about whether the object is >> _empty_. Not all empty objects have zero length, or even a length at all. >> (E.g. binary trees.) > > Conversely, not all objects that have length consider zero-length to be > false. Which is why truth-testing is defined by __nonzero__ with __len__ only the fall-back, for convenience. > Whether you test with "if a:" or "if len(a)>0", some objects > are going to be denied. If a class doesn't define __nonzero__ or __len__, it should. Unless it is meant to always be True. > Thing is, objects that don't have length have almost no overlapping > uses with lists (i.e., you'd hardly ever write a function that could > take an int or a list, unless you type check the argument or use only > object protocol stuff like id and getattr, or pass it to another > function that does the same). Iterators do have overlapping uses with > lists, but the "if a:" doesn't work for them, so it's moot. Sure it works for iterators. >>> it = iter([0]) >>> bool(it) True >>> it.next() 0 >>> bool(it) False Perhaps this behaviour has changed in version 2.5, if so, I'd like to hear the rationalisation before I declare it a mistake. > P.S. binary trees do have length: it's the number of nodes, just as the > number of keys is the length of a dict. I don't know what you were taught, but I was taught that binary trees have height and breadth. "Length" was never used for the number of nodes. If you go to the trouble of walking the tree, you obviously get the equivalent of a list with a length, but in all the texts I've read, walking the entire tree is the classic example of an expensive operation that you should try to avoid if you don't need to. The same goes for counting the number of nodes, unless you wanted to cache the result somewhere. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Fri, 27 Oct 2006 18:22:28 +, Antoon Pardon wrote: >>> And how do I express that a number has to be greater than >>> 100 into a Nothing vs Something dichotomy? Declare all >>> greater numbers as Something and the rest as Nothing? >> >> Well, would you declare numbers less than 100 False? > > No but the condition: x > 100, will map all numbers to > either True or False. Can you provide a condition that will > provide a mapping to Nothing and Something? Without > artificially mapping False to Nothing and True to Something? A > B maps to max(0, A-B) or more verbosely, "Remove B items from A items, stopping when there are no more items to remove. What is left over? Something or Nothing?" Likewise, A < B maps to max(0, B-A). -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Fri, 27 Oct 2006 17:35:58 +, Antoon Pardon wrote: > On 2006-10-27, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > >> But in this specific instance, I don't see any advantage to explicitly >> testing the length of a list. Antoon might think that is sufficiently >> polymorphic, but it isn't. He cares whether the object has zero _length_, >> but for true polymorphism, he should be caring about whether the object is >> _empty_. Not all empty objects have zero length, or even a length at all. >> (E.g. binary trees.) That's why Python classes can use a __nonzero__ >> method, falling back on __len__ only if __nonzero__ is not defined. > > Nobody can force you to write a container class that also provides a > __len__ method. But if you don't provide one then IMO it is your class > that deviates from standard practice. Mathematically, sets and > directories have no length either, yet the len function does provide > an answer if you give it a set or directory as an argument. Do you mean dictionary? Dictionaries, a.k.a. hash tables, aren't a standard mathematical data type. Even if they were, they have two "lengths" (size really): the size of the table, and the number of items in the table. In a high level language like Python, you don't care about the size of the table (since it will, I believe, automatically grow dynamically if you need it to), so number of items is the only "size" (length) you could care about. > So > it seems that python has generalised the len function to provide > the number of elements in the container. Sure. But what about a container where the number of elements isn't well-defined, e.g. iterators? Or something like a binary tree, where counting the number of items is relatively expensive, but telling whether it is empty or not is cheaper than dirt? Here's a real example: it can be expensive to count the number of files in a directory -- on my PC, it takes almost a third of a second to count a mere 15,000 files in a single directory. (There may be a more sensible way of counting the number of files under Linux than ls | wc -l, but if so I don't know it.) But why slog through 15,000 files if all you need to know is if the directory is empty or not? As soon as you see one file, you know it isn't empty. Stop counting! Who cares whether there is one file or 15,000 files? > I have written a Tree class(*). It can be used as a drop in replacement > anywhere where a directory is used, as long as there is a full order > relationship in the key domain. That tree class provides a __len__ > method that will anser with the number of items in the tree just > as a directory would and I see nothing wrong with that. And I'm happy for you. But imagine a container object that maps a URL to some piece of data fetched from the Internet. Counting the size of the Internet is infeasible -- even if you were willing to try, it could take *weeks* of computation to determine! But one can certainly tell if there is an Internet out there or not. Such an object would always be True, unless you had lost network connectivity. My container object will work perfectly well with "if internet" but not with "if len(internet) > 0". You could even iterate over it, sort of, by following links from one site to another. But why are you checking the length of a container before iterating over it? If you are writing something like this: if len(container) != 0: for item in container: do_something() then just stop it! > Of course I can't account for all possible ways someone wishes to > write a class, but I don't see what is wrong with counting on > the fact that an empty container has a length of zero. Because you shouldn't assume containers have well-defined lengths unless you actually care about the length, and you shouldn't assume that length of zero implies "nothing to see here" unless you *know* that this is the case. You should leave defining empty up to the container class itself. Otherwise, you might be right 99 times in a hundred, but that hundredth time will bite you. > I can write a container class where the truth value of an object > is independent of whether or not the object is empty and then > the "if obj:" idiom will fail to provide true polymorphism too. A class that deliberate breaks the semantics of Python truth testing just for the sake of breaking code really is a pathological case. Polymorphism doesn't mean "will work with anything without exception". -- Steve. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Sat, 28 Oct 2006 03:13:42 +0100, Steve Holden wrote: >> Python is not evaluating the truth of the matter, but, as Ms. Creighton >> would say, the "somethingness" of that which 10 > 5 evaluates to. (1 >> aka True) >> > >>> type(10>5) > > >>> > > It does seem that there is a specific type associated with the result of > a comparison, even though you would really like to to be "a number with > a hat on". Python bools really are subclassed from ints: >>> issubclass(bool, int) True They are ints wearing a Boolean hat. This was a controversial compromise. >> >>> (1 > 0) < 1 >> False >> >>> 1 > 0 < 1 >> True >> >>> 1 > (0 < 1) >> False >> >>> 10 > (0 < 1) >> True >> > I have no idea what you think that you are demonstrating here. Run through the expressions by hand: (1 > 0) < 1 True < 1 False The mere fact that you can compare bools with ints demonstrates that Python bools aren't "real" Booleans. >> Finally, while True/False is a good mental mapping for numeric >> comparisons, take the following: >> >> >>> if "Cliff is a pillar of the open source community": >> print "thank you" >> else: >> print "bugger off" >> >> bugger off >> >> Clearly this is not true. (Google Cliff/Dyer open source: only 11 >> hits.), but the string is *something* so the if block gets evaluated. >> > >>> if "The above example was bollocks": > ... print "You don't know what you are talking about" > ... else: > ... print "Sorry: of course you are perfectly correct" > ... > You don't know what you are talking about Cliff is making a point about semantics, and he's absolutely correct about it, although it is irrelevant since we're talking about two-value logic not semantics. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
At Friday 27/10/2006 23:13, Steve Holden wrote: J. Clifford Dyer wrote: > the one thing that Ms. Creighton points out that I can't get past is > that Python, even with its bool type, *still* evaluates somethingness > and nothingness, and True and False are just numbers with hats on. > > >>> True + 3 > 4 > >>> bool(True-1) > False > >>> bool(True-2) > True > >>> (10 > 5) + (10 < 5) > 1 Seems pretty clear to me that the situations you discuss above involve numeric coercions of a Boolean value. A "true" Boolean value should not be coerced into any other thing. True+1 is as meaningless as "A"+1, or even "1"+1. The fact is, bool is just an integer in disguise. I always regretted that Python just went mid-way moving onto a true Boolean type; I'd prefer it to stay as it was before bool was introduced. > Python is not evaluating the truth of the matter, but, as Ms. Creighton > would say, the "somethingness" of that which 10 > 5 evaluates to. (1 > aka True) > >>> type(10>5) >>> >>> bool.__mro__ (, , ) It does seem that there is a specific type associated with the result of a comparison, even though you would really like to to be "a number with a hat on". It *is* an integer with a hat on. >>> isinstance(True,int) True -- Gabriel Genellina Softlab SRL __ Correo Yahoo! Espacio para todos tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
J. Clifford Dyer wrote: > I do see how mapping to Truth/Falsehood is more natural, and I do > believe that one of the great things about python is that it feels > natural in so many ways, and hence makes it easy to produce code, but > the one thing that Ms. Creighton points out that I can't get past is > that Python, even with its bool type, *still* evaluates somethingness > and nothingness, and True and False are just numbers with hats on. > > >>> True + 3 > 4 > >>> bool(True-1) > False > >>> bool(True-2) > True > >>> (10 > 5) + (10 < 5) > 1 > > So when you say > > >>>if 10 > 5: > print "Yes!" > Seems pretty clear to me that the situations you discuss above involve numeric coercions of a Boolean value. > Python is not evaluating the truth of the matter, but, as Ms. Creighton > would say, the "somethingness" of that which 10 > 5 evaluates to. (1 > aka True) > >>> type(10>5) >>> It does seem that there is a specific type associated with the result of a comparison, even though you would really like to to be "a number with a hat on". > Furthermore, how do you explain this bizarreness in terms of "Truth" and > "Falsehood?" You have to go back to the fact that True=1 and that > REALLY, Python is dealing with somethingness and nothingness. It might > not be as direct a mental connection as True/False, but it is certainly > a more accurate one for understanding how Python works. > > >>> (1 > 0) < 1 > False > >>> 1 > 0 < 1 > True > >>> 1 > (0 < 1) > False > >>> 10 > (0 < 1) > True > I have no idea what you think that you are demonstrating here. > Finally, while True/False is a good mental mapping for numeric > comparisons, take the following: > > >>> if "Cliff is a pillar of the open source community": > print "thank you" > else: > print "bugger off" > > bugger off > > Clearly this is not true. (Google Cliff/Dyer open source: only 11 > hits.), but the string is *something* so the if block gets evaluated. > >>> if "The above example was bollocks": ... print "You don't know what you are talking about" ... else: ... print "Sorry: of course you are perfectly correct" ... You don't know what you are talking about >>> regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
I do see how mapping to Truth/Falsehood is more natural, and I do believe that one of the great things about python is that it feels natural in so many ways, and hence makes it easy to produce code, but the one thing that Ms. Creighton points out that I can't get past is that Python, even with its bool type, *still* evaluates somethingness and nothingness, and True and False are just numbers with hats on. >>> True + 3 4 >>> bool(True-1) False >>> bool(True-2) True >>> (10 > 5) + (10 < 5) 1 So when you say >>>if 10 > 5: ... print "Yes!" Python is not evaluating the truth of the matter, but, as Ms. Creighton would say, the "somethingness" of that which 10 > 5 evaluates to. (1 aka True) Furthermore, how do you explain this bizarreness in terms of "Truth" and "Falsehood?" You have to go back to the fact that True=1 and that REALLY, Python is dealing with somethingness and nothingness. It might not be as direct a mental connection as True/False, but it is certainly a more accurate one for understanding how Python works. >>> (1 > 0) < 1 False >>> 1 > 0 < 1 True >>> 1 > (0 < 1) False >>> 10 > (0 < 1) True Finally, while True/False is a good mental mapping for numeric comparisons, take the following: >>> if "Cliff is a pillar of the open source community": ... print "thank you" ... else: ... print "bugger off" bugger off Clearly this is not true. (Google Cliff/Dyer open source: only 11 hits.), but the string is *something* so the if block gets evaluated. Cheers, Cliff -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Fri, 27 Oct 2006 11:25:09 -0700 Carl Banks <[EMAIL PROTECTED]> wrote: #> P.S. binary trees do have length: it's the number of nodes, just as #> the number of keys is the length of a dict. I can't think of any #> objects that use indexing but don't have a length, Well, infinite lists (either circular or dynamically-growing) would be one (unless you consider infinity to be a valid value of length, of course). Dictionaries with default value would be another (of course, Python 2.5 defaultdict *does* have length, but I would claim it is a wart). But I agree those are pathological cases. -- Best wishes, Slawomir Nowaczyk ( [EMAIL PROTECTED] ) Programmer - A red-eyed, mumbling mammal capable of conversing with inanimate objects. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-27, Donn Cave <[EMAIL PROTECTED]> wrote: > In article <[EMAIL PROTECTED]>, > Antoon Pardon <[EMAIL PROTECTED]> wrote: > ... >> I think you are incorrect. > > Thanks! I rest my case! > >> And how do I express that a number has to be greater than >> 100 into a Nothing vs Something dichotomy? Declare all >> greater numbers as Something and the rest as Nothing? > > Well, would you declare numbers less than 100 False? No but the condition: x > 100, will map all numbers to either True or False. Can you provide a condition that will provide a mapping to Nothing and Something? Without artificially mapping False to Nothing and True to Something? > Think about it in more philosophical terms. What is Truth? > The Internet Encyclopedia of Philosophy may be some help > with this - http://www.iep.utm.edu/t/truth.htm I don't care about such philosophical issues. I also doubt that you could provide better answers if you would subsituted Somthingness for truth is that text. > Then when you get tired of that, suppose that "if" and > "while" are asking for "yes" and "no", instead of "true" > and "false", and ask yourself if we have the philosophical > problems with "yes" that we do with "true". Of course we have. Deciding whether a statment/condition is true or not is equivallent to deciding whether or not we should answer yes or no to a related question. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Steven D'Aprano wrote: > But in this specific instance, I don't see any advantage to explicitly > testing the length of a list. Antoon might think that is sufficiently > polymorphic, but it isn't. He cares whether the object has zero _length_, > but for true polymorphism, he should be caring about whether the object is > _empty_. Not all empty objects have zero length, or even a length at all. > (E.g. binary trees.) Conversely, not all objects that have length consider zero-length to be false. Whether you test with "if a:" or "if len(a)>0", some objects are going to be denied. Thing is, objects that don't have length have almost no overlapping uses with lists (i.e., you'd hardly ever write a function that could take an int or a list, unless you type check the argument or use only object protocol stuff like id and getattr, or pass it to another function that does the same). Iterators do have overlapping uses with lists, but the "if a:" doesn't work for them, so it's moot. OTOH, objects that have length but don't consider zero-length to be false (numpy arrays) do have overlapping uses with lists. So, as a practical matter, I'd be inclined to side with Antoon on this issue, even if it only increases polymorphism for certain people. "if a:" almost never increases polymorphism because almost no lengthless objects would work in that function anyways. Even if you don't use numpy arrays, there's little practical benefit of "if a:" except to save typing. If you do use numpy, it limits polymorphism. "if len(a)>0" does increase polymorphism because it allows for objects that have length but don't equate empty to false. P.S. binary trees do have length: it's the number of nodes, just as the number of keys is the length of a dict. I can't think of any objects that use indexing but don't have a length, except for poorly-implemented proxy objects. It's possible to define such types, but would that be a Pythonic use of indexing? Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-27, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > On Fri, 27 Oct 2006 09:16:57 +, Antoon Pardon wrote: > >>> I think it is a good time to remind people of some extremely well-thought >>> out opposition to the introduction of bools to Python from Laura Creighton: >>> >>> http://mail.python.org/pipermail/python-list/2002-April/095878.html >>> >>> She lost the debate, Guido had the final word and Python now has bools. >>> Take particular note of her description of Python distinguishing between >>> Something ("cat", 4, [0, 1, 2] etc) and Nothing ("", 0, [] etc). >> >> Yes and IMO that is a less usefull distinction than the distinction >> between True and False. When I write code I think in terms of >> conditions. In those conditions this has to be treated this way >> otherwise it has to be treated an other way. Conditions give >> results that are either True or False, not Something or Nothing. > > And if you read the thread that Laura Creighton's post is part of, you > will see that she acknowledges that most people think strongly in terms > of binary true/false yes/no states, and that this is often the wrong thing > to do. There are lots of human thought patterns that are unhealthy, and > binary is often one of them. The Nothing/Something dichotomy is just as binary as the True/False dichotomy. And in the case of deciding whether you will take the "then" branch or "else" branch I see nothing unhealthy in checking whether the condition was true or not. > The world is continuous, and our brains think in binary. No wonder people > have such trouble with concepts like evolution: The world may be continuous, programming structures are discrete. You take the "then" branch or not. In the latter case you can again decide to take the elif branch or not. There is nothing continuous in that. > - there is a continual chain of individuals such that every offspring of > an reptile is a reptile, and every parent of a mammal is a mammal, and > yet mammals are directly descended from reptiles. > > By I digress. This is too easy to get off topic... > > >> I don't think of 10 > 5 as Something while 5 < 10 would be >> Nothing. > > Not at all, you got your operators the wrong way around. Five certainly is > less than 10 in every counting system I've ever come across. I think you > meant 5 > 10 is Nothing. Yes that was a type, I meant I don't think of 5 > 10 as Nothing. > Certainly purely mathematical relations like GT and LT lend themselves > very well to true two-valued algebra. The thing to remember is that > Python's truth model is not the same as pure Boolean algebra. For > starters, it certainly is not two-valued! It is infinitely-valued. It's > just that many of those values are equivalent *in a Boolean context*. That it is infinitely-valued is a red herring. It is partitioned in two, so all these infinite values are mapped into two possibilities because at the end you have to decide a simple yes/no question. Will I repeat the loop or not. Will I take the "then" branch or not. > In Pascal, writing "x := 2; if x then..." would be an error, because x is > not a Boolean. But it is certainly useful to be able to write the > equivalent in Python. The designer of Pascal choose strict Boolean > algebra; the designer of Python choose a more flexible, less strict model. > > If you are going to argue for strict Booleans, like in Pascal, then > mathematical relations like GT and LT will be your poster-child. > > But if you are going to argue for Python's less strict truth model, then > you'll talk about lots of examples like this: > > if somelist: > # work with the list > else: > # nothing to work with In most case I just do: for el in somelist: which works for empty lists just as good as non-empty ones. So why should an empty list be treated differently from an non-empty one if it is used in a boolean context? >> So while the paradigma of the language may be the >> distinction of Something vs Nothing the programmer will often >> enough think in terms of True and False. > > If you read Laura's post, you will see that she is arguing strongly that > thinking about True and False is often -- usually! -- a mistake. Yes she argues that? So? I think she is wrong and her argument lacking. > I > acknowledge that there are cases where it is either necessary or desirable > to think in terms of True/False, but that is less common than you might > think. Control structures in programming languages do nothing else but decide things in terms of True/False. You may dress things up but in the end a statement like: if obj: Will evaluate/map into a two valued domain, where one value will lead you into the "then" branch and the other value will not. And IMO the more clearer the relationship between the written code and the final result the better. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-27, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > But in this specific instance, I don't see any advantage to explicitly > testing the length of a list. Antoon might think that is sufficiently > polymorphic, but it isn't. He cares whether the object has zero _length_, > but for true polymorphism, he should be caring about whether the object is > _empty_. Not all empty objects have zero length, or even a length at all. > (E.g. binary trees.) That's why Python classes can use a __nonzero__ > method, falling back on __len__ only if __nonzero__ is not defined. Nobody can force you to write a container class that also provides a __len__ method. But if you don't provide one then IMO it is your class that deviates from standard practice. Mathematically, sets and directories have no length either, yet the len function does provide an answer if you give it a set or directory as an argument. So it seems that python has generalised the len function to provide the number of elements in the container. I have written a Tree class(*). It can be used as a drop in replacement anywhere where a directory is used, as long as there is a full order relationship in the key domain. That tree class provides a __len__ method that will anser with the number of items in the tree just as a directory would and I see nothing wrong with that. Of course I can't account for all possible ways someone wishes to write a class, but I don't see what is wrong with counting on the fact that an empty container has a length of zero. I can write a container class where the truth value of an object is independent of whether or not the object is empty and then the "if obj:" idiom will fail to provide true polymorphism too. (*) http://www.pardon-sleeuwaegen.be/antoon/avltree.html -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
In article <[EMAIL PROTECTED]>, Antoon Pardon <[EMAIL PROTECTED]> wrote: ... > I think you are incorrect. Thanks! I rest my case! > And how do I express that a number has to be greater than > 100 into a Nothing vs Something dichotomy? Declare all > greater numbers as Something and the rest as Nothing? Well, would you declare numbers less than 100 False? Think about it in more philosophical terms. What is Truth? The Internet Encyclopedia of Philosophy may be some help with this - http://www.iep.utm.edu/t/truth.htm Then when you get tired of that, suppose that "if" and "while" are asking for "yes" and "no", instead of "true" and "false", and ask yourself if we have the philosophical problems with "yes" that we do with "true". Donn Cave, [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Fri, 27 Oct 2006 12:54:35 +0100, Steve Holden wrote: > Antoon Pardon wrote: >> On 2006-10-27, Fredrik Lundh <[EMAIL PROTECTED]> wrote: >> >>>Antoon Pardon wrote: >>> >>> >since you never publish any code, This is not True. You shouldn't confuse your lack of recollection with reality. >>> >>>pointers, please. >> >> >> Sorry, the answer is no. I don't care whether you can locate my code >> or not or wish to believe me or not. >> > Google finds 2 hits for "Anton Pardoon open source". You are ceratinly > keeping it well hidden. > > Few people have more right to call you on this than the effbot, well > known for his prolific output. This may come as a shock to some of us in the Open Source arena, but the care-factor of code is not necessarily tied to the number of distinct pieces of code released to the public by the code's author. Many people, for example, care a lot about the software running in nuclear reactors, regardless of whether or not the code's author is a prolific Open Source developer. Of course Fredrik has a proven track record, and the quality of his code is out there for any interested person to see. That means that the wise person, even if he disagrees with Fredrik, should take what he has to say seriously. If Fredrik is dismissive of Antoon's use of "if len(list) != 0" instead of "if list", we should take that opinion very seriously. But for all we know, Antoon's code might be responsible for keeping nuclear reactors running, planes in the air, missiles hitting their targets, or some other really critical application. His lack of visible code doesn't *necessarily* mean we should dismiss what he has to say -- it merely means that his track record is unproven to us. And even if he does nothing but write trivial scripts for his own use, that fact alone doesn't make his opinion wrong or foolish. But in this specific instance, I don't see any advantage to explicitly testing the length of a list. Antoon might think that is sufficiently polymorphic, but it isn't. He cares whether the object has zero _length_, but for true polymorphism, he should be caring about whether the object is _empty_. Not all empty objects have zero length, or even a length at all. (E.g. binary trees.) That's why Python classes can use a __nonzero__ method, falling back on __len__ only if __nonzero__ is not defined. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
*** Your mail has been scanned by InterScan MSS. *** On Thursday 26 October 2006 02:56, John Salerno wrote: > >>> s = 'hello' > >>> s == True > False > >>> if s: > print 'hi' > this isn't only a python behavior. the "if" test is valid for all non-zero variables. only None, 0 and False make the condition to jump over. F -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Fri, 27 Oct 2006 09:16:57 +, Antoon Pardon wrote: >> I think it is a good time to remind people of some extremely well-thought >> out opposition to the introduction of bools to Python from Laura Creighton: >> >> http://mail.python.org/pipermail/python-list/2002-April/095878.html >> >> She lost the debate, Guido had the final word and Python now has bools. >> Take particular note of her description of Python distinguishing between >> Something ("cat", 4, [0, 1, 2] etc) and Nothing ("", 0, [] etc). > > Yes and IMO that is a less usefull distinction than the distinction > between True and False. When I write code I think in terms of > conditions. In those conditions this has to be treated this way > otherwise it has to be treated an other way. Conditions give > results that are either True or False, not Something or Nothing. And if you read the thread that Laura Creighton's post is part of, you will see that she acknowledges that most people think strongly in terms of binary true/false yes/no states, and that this is often the wrong thing to do. There are lots of human thought patterns that are unhealthy, and binary is often one of them. The world is continuous, and our brains think in binary. No wonder people have such trouble with concepts like evolution: - there is a continual chain of individuals such that every offspring of an reptile is a reptile, and every parent of a mammal is a mammal, and yet mammals are directly descended from reptiles. By I digress. This is too easy to get off topic... > I don't think of 10 > 5 as Something while 5 < 10 would be > Nothing. Not at all, you got your operators the wrong way around. Five certainly is less than 10 in every counting system I've ever come across. I think you meant 5 > 10 is Nothing. Certainly purely mathematical relations like GT and LT lend themselves very well to true two-valued algebra. The thing to remember is that Python's truth model is not the same as pure Boolean algebra. For starters, it certainly is not two-valued! It is infinitely-valued. It's just that many of those values are equivalent *in a Boolean context*. In Pascal, writing "x := 2; if x then..." would be an error, because x is not a Boolean. But it is certainly useful to be able to write the equivalent in Python. The designer of Pascal choose strict Boolean algebra; the designer of Python choose a more flexible, less strict model. If you are going to argue for strict Booleans, like in Pascal, then mathematical relations like GT and LT will be your poster-child. But if you are going to argue for Python's less strict truth model, then you'll talk about lots of examples like this: if somelist: # work with the list else: # nothing to work with > So while the paradigma of the language may be the > distinction of Something vs Nothing the programmer will often > enough think in terms of True and False. If you read Laura's post, you will see that she is arguing strongly that thinking about True and False is often -- usually! -- a mistake. I acknowledge that there are cases where it is either necessary or desirable to think in terms of True/False, but that is less common than you might think. > So IMO it would have > been better if python had made the distinction between True and > False and so made the programmer code the Something/Nothing > disctinction explicitly. I don't understand what you are saying here, unless it is that you believe that Python should have strict Pascal-style Booleans. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Antoon Pardon wrote: > On 2006-10-27, Fredrik Lundh <[EMAIL PROTECTED]> wrote: > >>Antoon Pardon wrote: >> >> since you never publish any code, >>> >>>This is not True. You shouldn't confuse your lack of recollection >>>with reality. >> >>pointers, please. > > > Sorry, the answer is no. I don't care whether you can locate my code > or not or wish to believe me or not. > ... though I might have got more hits by spelling your name correctly :) regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Antoon Pardon wrote: > On 2006-10-27, Fredrik Lundh <[EMAIL PROTECTED]> wrote: > >>Antoon Pardon wrote: >> >> since you never publish any code, >>> >>>This is not True. You shouldn't confuse your lack of recollection >>>with reality. >> >>pointers, please. > > > Sorry, the answer is no. I don't care whether you can locate my code > or not or wish to believe me or not. > Google finds 2 hits for "Anton Pardoon open source". You are ceratinly keeping it well hidden. Few people have more right to call you on this than the effbot, well known for his prolific output. regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-27, Fredrik Lundh <[EMAIL PROTECTED]> wrote: > Antoon Pardon wrote: > >>> since you never publish any code, >> >> This is not True. You shouldn't confuse your lack of recollection >> with reality. > > pointers, please. Sorry, the answer is no. I don't care whether you can locate my code or not or wish to believe me or not. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Antoon Pardon wrote: >> since you never publish any code, > > This is not True. You shouldn't confuse your lack of recollection > with reality. pointers, please. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-27, Fredrik Lundh <[EMAIL PROTECTED]> wrote: > Antoon Pardon wrote: > >> The latter will treat None and False the same as [], () and {}, >> which in most of my code is not what I want. > > since you never publish any code, This is not True. You shouldn't confuse your lack of recollection with reality. > what you do in your code is not very interesting to anyone. I doubt I'm the only one who has code that treats None and False differently from [], () and {} -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-26, Steve Holden <[EMAIL PROTECTED]> wrote: > John Coleman wrote: >> As far as using non-booleans as conditions - I just think that if you >> want a certain block of code to be executed only if, for example, a >> list is non-empty, why not *say* so? I think "if my_list != []:" just >> reads better than "if my_list:". I would think that my preferences >> there mesh with "Explicit is better than implicit" but apparently not. >> > Maybe so, but that "rule" (and let's not forget that the zen is not > actually a set of prescriptive rules but rather guidelines for the > informed) is immediately preceded by the most important "rule" of all: > "Beautiful is better than ugly". Nobody will shout at you (well, > hopefully, not on this list they won't) for writing > >if my_list != []: > ... That depends on what you consider as shouting. My impression is that if people come here with a problem and post a sample of code to illustrate. That if that code would contain something like the above about half of the responses will be about the code not following python idiom without further providing anything helpfull with the actual problem. Now you may not consider that as shouting but I guess it can be just as intimidating. >> > It probably will, but I wouldn't get too hung up on what's definitely a > small point. Enjoy Python the way it is, and the way you are. You and > Python will definitely come to an accommodation (and you will love the > combination of discipline and freedom that it brings to programming > style). Welcome to the language! I'll second that. Python has it warts, but so has any language. Chances are John will find the warts of python are minor issues compared with other languages. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Antoon Pardon wrote: > The latter will treat None and False the same as [], () and {}, > which in most of my code is not what I want. since you never publish any code, what you do in your code is not very interesting to anyone. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-26, Donn Cave <[EMAIL PROTECTED]> wrote: > In article <[EMAIL PROTECTED]>, > Steve Holden <[EMAIL PROTECTED]> wrote: > ... >> Maybe so, but that "rule" (and let's not forget that the zen is not >> actually a set of prescriptive rules but rather guidelines for the >> informed) is immediately preceded by the most important "rule" of all: >> "Beautiful is better than ugly". Nobody will shout at you (well, >> hopefully, not on this list they won't) for writing >> >>if my_list != []: >> ... >> >> in your code, but if they have to incorporate it into their own they >> will almost certainly reduce it to >> >>if my_list: >> >> >> It's just idiomatic in Python, the same way that "'Sup?" is idiomatic in >> English (or what passes for it nowadays ;-) but grates on those who >> aren't used to hearing it. > > It is idiomatic, but not _just_ idiomatic. The former requires > a list object (or a tricky __eq__()), the latter works with a variety > of objects, exhibiting a useful polymorphism. The latter will treat None and False the same as [], () and {}, which in most of my code is not what I want. In most cases I find testing for an empty sequence (however you do it) useless, because the loop over the sequence does whatever I want if it is empty. In cases where I do want to test for it I usually write: if len(my_list) > 0: That provides the polymorphism that is usefull to me and doesn't treat None the same as an empty sequence. > As for similarities between computer programming languages > and natural languages, I think that breaks down pretty fast. > > Part of the problem is something that pinches Python pretty > hard right here, a lack of words that conveniently express > important concepts in the language. A few posts back, Carl > Banks made a distinction between "equaling" and "being", and > if I understood that right, it expresses a fundamental notion > about the meaning of Python's "if", "while" etc. statements. > Unfortunately, though, English conflates existence and identity > in this word ("be"), so it's not going to serve our purposes > very well, and when it comes to words like "if" -- well, we > just have to use what we have. > > If there were better words to use with the notion of > "something-ness", I think we would see booleans as a silly > thing of little use to Python programmers. I think you are incorrect. Decisions have to be made and they are made based on conditions. Conditions are expressed in terms of True and False not in terms of Nothing or Something. That is how IMO people think. You can't change that just because python is implemented with the Nothing vs Something distinction in mind. > If you can see > "if" and "while" as constructs that respond to something-ness, > you will appreciate idiomatic Python better, because that > arguably is just what it's about. And how do I express that a number has to be greater than 100 into a Nothing vs Something dichotomy? Declare all greater numbers as Something and the rest as Nothing? -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-26, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > On Wed, 25 Oct 2006 19:19:59 +, John Salerno wrote: > >> Oh!!! I get it now! I was thinking that >> >> if s >> >> was the same as >> >> if s == True > > No. But you know that now :) > >> because I know sometimes you can write if statements this way (though >> it's wordy). > > You can, but shouldn't. > > >> But what I didn't realize was that in the cases I was >> thinking of, 's' was an expression that evaluated to a boolean value, >> not an actual value of some other type! >> >> So I suppose >> >> if (10 > 5) > > Is the same as: > > if True > > because (10 > 5) evaluates as True. > > >> would be the same as >> >> if (10 > 5) == True > > Did you mean > > if (10 > 5) == True == True > > or > > if (10 > 5) == True == True == True > > or even > > if (10 > 5) == True == True == True == True > > I hope you see my point now. > > >> because (10 > 5) does evaluate to "True". > > I think it is a good time to remind people of some extremely well-thought > out opposition to the introduction of bools to Python from Laura Creighton: > > http://mail.python.org/pipermail/python-list/2002-April/095878.html > > She lost the debate, Guido had the final word and Python now has bools. > Take particular note of her description of Python distinguishing between > Something ("cat", 4, [0, 1, 2] etc) and Nothing ("", 0, [] etc). Yes and IMO that is a less usefull distinction than the distinction between True and False. When I write code I think in terms of conditions. In those conditions this has to be treated this way otherwise it has to be treated an other way. Conditions give results that are either True or False, not Something or Nothing. I don't think of 10 > 5 as Something while 5 < 10 would be Nothing. So while the paradigma of the language may be the distinction of Something vs Nothing the programmer will often enough think in terms of True and False. So IMO it would have been better if python had made the distinction between True and False and so made the programmer code the Something/Nothing disctinction explicitly. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: Truth value of iterators [was: question about True values)
Robert Kern wrote: > Ben Finney wrote: > > > Would it make sense to *define* a truth value for iterators? Or at > > least to enable those that *are* able to say "I'm empty" to do so in a > > way that boolean contexts can interpret as "false"? > > > > Perhaps allowing (but not requiring) an iterator object to grow a > > 'len' method is the simplest way. > > And indeed, they are already allowed to do so. > > Python 2.4.1 (#2, Mar 31 2005, 00:05:10) > Type "copyright", "credits" or "license" for more information. > > In [1]: len(iter(())) > Out[1]: 0 > > In [2]: bool(iter(())) > Out[2]: False And indeed, the built-in iterators have already backed away from this idea. Python 2.5c2 (r25c2:51859, Sep 13 2006, 09:50:32) [GCC 4.1.2 20060814 (prerelease) (Debian 4.1.1-11)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> len(iter(())) Traceback (most recent call last): File "", line 1, in TypeError: object of type 'tupleiterator' has no len() >>> bool(iter(())) True Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: Truth value of iterators [was: question about True values)
Ben Finney wrote: > "Carl Banks" <[EMAIL PROTECTED]> writes: > > > An iterator is not a sequence, and it's impossible to determine > > whether an iterator is "empty" in general, except by trying to get > > an item from it. [...] > > > > IMO, this is big time wart in the language. Iterators have no > > calculatable truth value; for many other types a truth value doesn't > > make sense (for instance: function objects, type objects, modules, > > user-defined types that don't bother with __nonzero__). Using such > > objects in a boolean context is almost always an error. > > It still seems like a reasonable thing for a programmer to do though, > even if the language doesn't currently support it. > > Would it make sense to *define* a truth value for iterators? Or at > least to enable those that *are* able to say "I'm empty" to do so in a > way that boolean contexts can interpret as "false"? Again, it's impossible to tell if an iterator is empty in general except by trying to get an item. You could add a feature to iterators that fetches an item and stores it, but that would a. be a pain in the neck for everyone, and b. adversely affect iterators that depend on outside factors. > Perhaps allowing (but not requiring) an iterator object to grow a > 'len' method is the simplest way. I could live with some iterators defining __len__ or even __nonzero__, as long as iterators that couldn't determine these things threw an exception rather than returning a fake value. I'd rather no iterators did this, though, because having these options makes it likely that some programmers will write code supporting only "len-able iterators", thus hindering polymorphism unnecessarily. I'd rather people use iterators as iterators and not as temporally-challenged lists. However, it's certainly helpful sometimes to know if an iterator has any items left (say, to possibly avoid some initialization code). I don't think this should be a part of iterator protocol, but maybe it'd be nice if somewhere in the the standard library there was an iterator type such as this: class EmptySavvyIterator(object): noitem = object() def __init__(self,iterable): self.iterator = iter(iterable) self.storage = self.noitem def __iter__(self): return self def next(self): if self.storage is not self.noitem: item = self.storage self.storage = self.noitem return item return self.iterator.next() def empty(self): if self.storage is not self.noitem: return False try: self.storage = self.iterator.next() except StopIteration: return True return False # if you must... def __nonzero__(self): return not self.empty() Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: Truth value of iterators [was: question about True values)
Ben Finney wrote: > Would it make sense to *define* a truth value for iterators? Or at > least to enable those that *are* able to say "I'm empty" to do so in a > way that boolean contexts can interpret as "false"? > > Perhaps allowing (but not requiring) an iterator object to grow a > 'len' method is the simplest way. And indeed, they are already allowed to do so. Python 2.4.1 (#2, Mar 31 2005, 00:05:10) Type "copyright", "credits" or "license" for more information. In [1]: len(iter(())) Out[1]: 0 In [2]: bool(iter(())) Out[2]: False -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco -- http://mail.python.org/mailman/listinfo/python-list
Truth value of iterators [was: question about True values)
"Carl Banks" <[EMAIL PROTECTED]> writes: > An iterator is not a sequence, and it's impossible to determine > whether an iterator is "empty" in general, except by trying to get > an item from it. [...] > > IMO, this is big time wart in the language. Iterators have no > calculatable truth value; for many other types a truth value doesn't > make sense (for instance: function objects, type objects, modules, > user-defined types that don't bother with __nonzero__). Using such > objects in a boolean context is almost always an error. It still seems like a reasonable thing for a programmer to do though, even if the language doesn't currently support it. Would it make sense to *define* a truth value for iterators? Or at least to enable those that *are* able to say "I'm empty" to do so in a way that boolean contexts can interpret as "false"? Perhaps allowing (but not requiring) an iterator object to grow a 'len' method is the simplest way. -- \ "I like my dental hygenist, I think she's very pretty; so when | `\I go to have my teeth cleaned, while I'm in the waiting room I | _o__) eat an entire box of cookies." -- Steven Wright | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Ben Finney wrote: > Gabriel Genellina <[EMAIL PROTECTED]> writes: > > > At Wednesday 25/10/2006 23:29, Paul Rubin wrote: > > >Steve Holden <[EMAIL PROTECTED]> writes: > > >I get that iter(()) is True (Python 2.3.4). > > > > It's False on 2.4.2 - and perhaps it's what one would expect, but > > since this behavior is not documented anywhere, one should not count > > on it. Good advice, because on 2.5 it's True again. > Doesn't this fall under "any empty sequence" in the following list of > evaluates-to-false: Nope. An iterator is not a sequence, and it's impossible to determine whether an iterator is "empty" in general, except by trying to get an item from it. So even in 2.4.3 some "empty" iterators return True: >>> a = [] >>> bool(x for x in a) True The only reasonable advice is to avoid the direct boolean test ("if a:") altogether if you want to support iterators. Unfortunately, iterators and lists have a lot of overlapping use, and it's very common to test for emptiness of lists using "if a:". If one tries to use an iterator where a list is expected it could lead to a silent failure. IMO, this is big time wart in the language. Iterators have no calculatable truth value; for many other types a truth value doesn't make sense (for instance: function objects, type objects, modules, user-defined types that don't bother with __nonzero__). Using such objects in a boolean context is almost always an error. Objects of these types should raise exceptions when used as a boolen. numpy arrays wisely already do this. (I'll stop short of mentioning that, because neither numpy arrays nor iterators consider "empty" to be "false", the idea that "empty" is "false" is very far from self-evident; therefore lists, tuples, dicts, and sets should also raise exceptions when used as a boolean. I won't mention that, though.) Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Ben Finney wrote: > Gabriel Genellina <[EMAIL PROTECTED]> writes: > > >>At Wednesday 25/10/2006 23:29, Paul Rubin wrote: >> >>>Steve Holden <[EMAIL PROTECTED]> writes: >>>I get that iter(()) is True (Python 2.3.4). >> No I didn't - that was Paul Rubin. >>It's False on 2.4.2 - and perhaps it's what one would expect, but >>since this behavior is not documented anywhere, one should not count >>on it. > > > Doesn't this fall under "any empty sequence" in the following list of > evaluates-to-false: > > http://docs.python.org/lib/truth.html> > regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
At Thursday 26/10/2006 19:57, Ben Finney wrote: Gabriel Genellina <[EMAIL PROTECTED]> writes: > At Wednesday 25/10/2006 23:29, Paul Rubin wrote: > >Steve Holden <[EMAIL PROTECTED]> writes: > >I get that iter(()) is True (Python 2.3.4). > > It's False on 2.4.2 - and perhaps it's what one would expect, but > since this behavior is not documented anywhere, one should not count > on it. Doesn't this fall under "any empty sequence" in the following list of evaluates-to-false: http://docs.python.org/lib/truth.html> Not exactly, because an iterator is not a sequence. -- Gabriel Genellina Softlab SRL __ Correo Yahoo! Espacio para todos tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Gabriel Genellina <[EMAIL PROTECTED]> writes: > At Wednesday 25/10/2006 23:29, Paul Rubin wrote: > >Steve Holden <[EMAIL PROTECTED]> writes: > >I get that iter(()) is True (Python 2.3.4). > > It's False on 2.4.2 - and perhaps it's what one would expect, but > since this behavior is not documented anywhere, one should not count > on it. Doesn't this fall under "any empty sequence" in the following list of evaluates-to-false: http://docs.python.org/lib/truth.html> -- \"If you continue running Windows, your system may become | `\ unstable." -- Microsoft, Windows 95 BSOD message | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
At Wednesday 25/10/2006 23:29, Paul Rubin wrote: Steve Holden <[EMAIL PROTECTED]> writes: > Gabriel Genellina wrote: > > iter(()) I get that iter(()) is True (Python 2.3.4). It's False on 2.4.2 - and perhaps it's what one would expect, but since this behavior is not documented anywhere, one should not count on it. -- Gabriel Genellina Softlab SRL __ Correo Yahoo! Espacio para todos tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
In article <[EMAIL PROTECTED]>, Steve Holden <[EMAIL PROTECTED]> wrote: ... > Maybe so, but that "rule" (and let's not forget that the zen is not > actually a set of prescriptive rules but rather guidelines for the > informed) is immediately preceded by the most important "rule" of all: > "Beautiful is better than ugly". Nobody will shout at you (well, > hopefully, not on this list they won't) for writing > >if my_list != []: > ... > > in your code, but if they have to incorporate it into their own they > will almost certainly reduce it to > >if my_list: > > > It's just idiomatic in Python, the same way that "'Sup?" is idiomatic in > English (or what passes for it nowadays ;-) but grates on those who > aren't used to hearing it. It is idiomatic, but not _just_ idiomatic. The former requires a list object (or a tricky __eq__()), the latter works with a variety of objects, exhibiting a useful polymorphism. As for similarities between computer programming languages and natural languages, I think that breaks down pretty fast. Part of the problem is something that pinches Python pretty hard right here, a lack of words that conveniently express important concepts in the language. A few posts back, Carl Banks made a distinction between "equaling" and "being", and if I understood that right, it expresses a fundamental notion about the meaning of Python's "if", "while" etc. statements. Unfortunately, though, English conflates existence and identity in this word ("be"), so it's not going to serve our purposes very well, and when it comes to words like "if" -- well, we just have to use what we have. If there were better words to use with the notion of "something-ness", I think we would see booleans as a silly thing of little use to Python programmers. If you can see "if" and "while" as constructs that respond to something-ness, you will appreciate idiomatic Python better, because that arguably is just what it's about. Donn Cave, [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On Wed, 25 Oct 2006 19:19:59 +, John Salerno wrote: > Oh!!! I get it now! I was thinking that > > if s > > was the same as > > if s == True No. But you know that now :) > because I know sometimes you can write if statements this way (though > it's wordy). You can, but shouldn't. > But what I didn't realize was that in the cases I was > thinking of, 's' was an expression that evaluated to a boolean value, > not an actual value of some other type! > > So I suppose > > if (10 > 5) Is the same as: if True because (10 > 5) evaluates as True. > would be the same as > > if (10 > 5) == True Did you mean if (10 > 5) == True == True or if (10 > 5) == True == True == True or even if (10 > 5) == True == True == True == True I hope you see my point now. > because (10 > 5) does evaluate to "True". I think it is a good time to remind people of some extremely well-thought out opposition to the introduction of bools to Python from Laura Creighton: http://mail.python.org/pipermail/python-list/2002-April/095878.html She lost the debate, Guido had the final word and Python now has bools. Take particular note of her description of Python distinguishing between Something ("cat", 4, [0, 1, 2] etc) and Nothing ("", 0, [] etc). -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Skip> string "" Skip> list[] Skip> tuple () Skip> dict{} Skip> int 0 Skip> float 0.0 Skip> complex 0j Skip> set set() Skip> Skip> Any other value besides the above will compare as "not false". >> And today's question for the novices is: which Python type did Skip >> miss from the above list? Ben>bool False In my rush to reply I missed several others as well. Elucidation left as an exercise for the reader. Skip -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John Coleman wrote: > Donn Cave wrote: > >>In article <[EMAIL PROTECTED]>, >> "John Coleman" <[EMAIL PROTECTED]> wrote: >> >> >>>Very good point, though one could argue perhaps that when one is >>>comparing an object with a truth value then one is implicitly asking >>>for the truth value of that object >> >>On the contrary -- since there is normally no need to ever >>compare an object with a truth value, then I would interpret >>this usage as an attempt to distinguish True or False from >>other objects in general. Some kind of placeholders for >>missing values, who knows. I'm not saying it's a great idea, >>but it could work in recent versions of Python. >> >> >>>This would make code like 'if s: ' equivalent >>>to 'if s == True:' with a possible gain in readability. But - as you >>>demonstrate the cost of that (minimal) gain in readability would be too >>>high. In any event - I think it is mostly bad style to use a >>>non-boolean variable in 'if s:' - it reminds me too much of obscure C >>>code (though others might disagree). >> >>Others will indeed disagree. I don't think you'll find >>much support for this position. But it's not as bad as >>your notion that "if s == True", where s is not a boolean >>object, might represent a gain in readability. That really >>redefines readability. >> >> Donn Cave, [EMAIL PROTECTED] > > > As far as readability goes - most computer languages have a surface > syntax which is (by design) vaguely similiar to the syntax of a natural > language like English. Thus statements roughly correspond to sentences. > For example, you can see a subject-verb-object pattern in "x=3". Given > a genuinely boolean construct like x < 2, "if x < 2:" *sounds* right to > a human reader. Similarly, given a good boolean variable with a > descriptive name like "found", the fragment "if found:" sounds ok. But > - given a non-boolean variable like "product_name" - writing "if > product_name:" sounds (to my ears) a little jarring - it sounds like a > sentence fragment. It's like saying "If Bob" - If Bob *what*? Goes to > the store? answers the telephone? Finish the damn thought! Now, if you > were to (from some strange reason) use "product_name" as if it were a > truth value then (to my ears) it would both make your intentions more > clear and sound less fragmentary if you could say "if product_name == > True:". When you use "product_name" as the condition of an if statement > then in that context it is *functioning* as a truth value so (naively) > what could be wrong with comparing it to a truth value? I don't > advocate any change in Python here - just pointing out that the idea of > allowing "if s:" and "if s == True:" to be always equivalent in the > interest of readability isn't *that* strange. It doesn't constitute a > redefinition of readability. > Yes, but you're talking about *your* ears there. I was pointing out, as others have, that "if product_name" is such a deeply-ingrained Python idiom that you can use how natural it "sounds" to you as a measure of your progress in the language. > As far as using non-booleans as conditions - I just think that if you > want a certain block of code to be executed only if, for example, a > list is non-empty, why not *say* so? I think "if my_list != []:" just > reads better than "if my_list:". I would think that my preferences > there mesh with "Explicit is better than implicit" but apparently not. > Maybe so, but that "rule" (and let's not forget that the zen is not actually a set of prescriptive rules but rather guidelines for the informed) is immediately preceded by the most important "rule" of all: "Beautiful is better than ugly". Nobody will shout at you (well, hopefully, not on this list they won't) for writing if my_list != []: ... in your code, but if they have to incorporate it into their own they will almost certainly reduce it to if my_list: It's just idiomatic in Python, the same way that "'Sup?" is idiomatic in English (or what passes for it nowadays ;-) but grates on those who aren't used to hearing it. > I'm just starting out with Python with most of my programming in recent > years being in various dialects of Visual Basic (which probably > explains a lot). What attracts me to Python so far is the cool slice > operations, the iterators, the libraries and the convience of > programming in a REPL environment. So far, the ability to use "cat" as > a part-time substitute for True just strikes me as a curiousity - but > maybe that will change with time. > It probably will, but I wouldn't get too hung up on what's definitely a small point. Enjoy Python the way it is, and the way you are. You and Python will definitely come to an accommodation (and you will love the combination of discipline and freedom that it brings to programming style). Welcome to the language! regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skyp
Re: question about True values
Donn Cave wrote: > In article <[EMAIL PROTECTED]>, > "John Coleman" <[EMAIL PROTECTED]> wrote: > > > Very good point, though one could argue perhaps that when one is > > comparing an object with a truth value then one is implicitly asking > > for the truth value of that object > > On the contrary -- since there is normally no need to ever > compare an object with a truth value, then I would interpret > this usage as an attempt to distinguish True or False from > other objects in general. Some kind of placeholders for > missing values, who knows. I'm not saying it's a great idea, > but it could work in recent versions of Python. > > > This would make code like 'if s: ' equivalent > > to 'if s == True:' with a possible gain in readability. But - as you > > demonstrate the cost of that (minimal) gain in readability would be too > > high. In any event - I think it is mostly bad style to use a > > non-boolean variable in 'if s:' - it reminds me too much of obscure C > > code (though others might disagree). > > Others will indeed disagree. I don't think you'll find > much support for this position. But it's not as bad as > your notion that "if s == True", where s is not a boolean > object, might represent a gain in readability. That really > redefines readability. > >Donn Cave, [EMAIL PROTECTED] As far as readability goes - most computer languages have a surface syntax which is (by design) vaguely similiar to the syntax of a natural language like English. Thus statements roughly correspond to sentences. For example, you can see a subject-verb-object pattern in "x=3". Given a genuinely boolean construct like x < 2, "if x < 2:" *sounds* right to a human reader. Similarly, given a good boolean variable with a descriptive name like "found", the fragment "if found:" sounds ok. But - given a non-boolean variable like "product_name" - writing "if product_name:" sounds (to my ears) a little jarring - it sounds like a sentence fragment. It's like saying "If Bob" - If Bob *what*? Goes to the store? answers the telephone? Finish the damn thought! Now, if you were to (from some strange reason) use "product_name" as if it were a truth value then (to my ears) it would both make your intentions more clear and sound less fragmentary if you could say "if product_name == True:". When you use "product_name" as the condition of an if statement then in that context it is *functioning* as a truth value so (naively) what could be wrong with comparing it to a truth value? I don't advocate any change in Python here - just pointing out that the idea of allowing "if s:" and "if s == True:" to be always equivalent in the interest of readability isn't *that* strange. It doesn't constitute a redefinition of readability. As far as using non-booleans as conditions - I just think that if you want a certain block of code to be executed only if, for example, a list is non-empty, why not *say* so? I think "if my_list != []:" just reads better than "if my_list:". I would think that my preferences there mesh with "Explicit is better than implicit" but apparently not. I'm just starting out with Python with most of my programming in recent years being in various dialects of Visual Basic (which probably explains a lot). What attracts me to Python so far is the cool slice operations, the iterators, the libraries and the convience of programming in a REPL environment. So far, the ability to use "cat" as a part-time substitute for True just strikes me as a curiousity - but maybe that will change with time. -John Coleman -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
"Robert Kern" <[EMAIL PROTECTED]> wrote: 8<-- > It's a bit of an abuse on the English language, but what isn't in software? jumps used not to be - Hendrik -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John Coleman wrote: > Paul Rubin wrote: > > "John Coleman" <[EMAIL PROTECTED]> writes: > > > > then "x == 3" is false, but "int(x) == 3" is true. > > > But then why is 3.0 == 3 true? They are different types. > > > > The 3 gets converted to float, like when you say > > > > x = 3.1 + 3 > > > > the result is 6.1. > > Yes - it just seems that there isn't a principled reason for implicitly > converting 3 to 3.0 in 3.0 == 3 but not implicitly converting "cat" to > boolean in "cat" == true. Because being true is not the same as equaling True. == is a test for equaling, not being. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Paul Rubin <"http://phr.cx"@NOSPAM.invalid> writes: > Max Erickson <[EMAIL PROTECTED]> writes: > > > [Steve:] There's still a very obvious omission ... > > > > bool. > > > > unicode and long if you are fussy. > > There's another. Imagine a datatype for Discordian religious > leaders and consider what a genderless one would be called. Hah! Not as obvious as the omission of 'bool', but: NoneType None -- \ "A man's only as old as the woman he feels." -- Groucho Marx | `\ | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Max Erickson <[EMAIL PROTECTED]> writes: > > [Steve:] There's still a very obvious omission ... > > bool. > > unicode and long if you are fussy. There's another. Imagine a datatype for Discordian religious leaders and consider what a genderless one would be called. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Steve Holden <[EMAIL PROTECTED]> wrote: > Gabriel Genellina wrote: >> At Wednesday 25/10/2006 22:29, Terry Reedy wrote: >> >>> >> the string class's "nil" value. Each of the builtin types >>> >> has such an "empty" or "nil" value: >>> >> >>> >> string "" >>> >> list[] >>> >> tuple () >>> >> dict{} >>> >> int 0 >>> >> float 0.0 >>> >> complex 0j >>> >> set set() >>> >> >>> >> Any other value besides the above will compare as "not >>> >> false". >>> >> >>> > >>> > And today's question for the novices is: which Python type >>> > did Skip >>> miss >>> > from the above list? >>> >>> more that one: >>> >>> 0L >>> decimal.Decimal(0) # is decimal.Decimal('0'), also >>> u'' >>> array.array('c') # or any other typecode, I suspect, without >>> initializer >> >> >> Just for fun: >> buffer('') >> frozenset() >> iter(()) >> xrange(0) >> > There's still a very obvious omission ... > > regards > Steve bool. unicode and long if you are fussy. max -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Steve Holden <[EMAIL PROTECTED]> writes: > Gabriel Genellina wrote: > > Just for fun: > > buffer('') > > frozenset() > > iter(()) > > xrange(0) I get that iter(()) is True (Python 2.3.4). > [Steve:] There's still a very obvious omission ... Hehehe... -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Steve Holden <[EMAIL PROTECTED]> writes: > [EMAIL PROTECTED] wrote: > > Each of the builtin types has such an "empty" or "nil" value: > > > > string "" > > list[] > > tuple () > > dict{} > > int 0 > > float 0.0 > > complex 0j > > set set() > > > > Any other value besides the above will compare as "not false". > > And today's question for the novices is: which Python type did Skip > miss from the above list? Is it cheating if I read this page: http://docs.python.org/lib/truth.html> -- \ "I always wanted to be somebody. I see now that I should have | `\ been more specific." -- Lily Tomlin | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Gabriel Genellina wrote: > At Wednesday 25/10/2006 22:29, Terry Reedy wrote: > >> >> the string class's "nil" value. Each of the builtin types has such an >> >> "empty" or "nil" value: >> >> >> >> string "" >> >> list[] >> >> tuple () >> >> dict{} >> >> int 0 >> >> float 0.0 >> >> complex 0j >> >> set set() >> >> >> >> Any other value besides the above will compare as "not false". >> >> >> > >> > And today's question for the novices is: which Python type did Skip >> miss >> > from the above list? >> >> more that one: >> >> 0L >> decimal.Decimal(0) # is decimal.Decimal('0'), also >> u'' >> array.array('c') # or any other typecode, I suspect, without initializer > > > Just for fun: > buffer('') > frozenset() > iter(()) > xrange(0) > There's still a very obvious omission ... regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
At Wednesday 25/10/2006 22:29, Terry Reedy wrote: >> the string class's "nil" value. Each of the builtin types has such an >> "empty" or "nil" value: >> >> string "" >> list[] >> tuple () >> dict{} >> int 0 >> float 0.0 >> complex 0j >> set set() >> >> Any other value besides the above will compare as "not false". >> > > And today's question for the novices is: which Python type did Skip miss > from the above list? more that one: 0L decimal.Decimal(0) # is decimal.Decimal('0'), also u'' array.array('c') # or any other typecode, I suspect, without initializer Just for fun: buffer('') frozenset() iter(()) xrange(0) -- Gabriel Genellina Softlab SRL __ Correo Yahoo! Espacio para todos tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
"Steve Holden" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] >> the string class's "nil" value. Each of the builtin types has such an >> "empty" or "nil" value: >> >> string "" >> list[] >> tuple () >> dict{} >> int 0 >> float 0.0 >> complex 0j >> set set() >> >> Any other value besides the above will compare as "not false". >> > > And today's question for the novices is: which Python type did Skip miss > from the above list? more that one: 0L decimal.Decimal(0) # is decimal.Decimal('0'), also u'' array.array('c') # or any other typecode, I suspect, without initializer Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Steve Holden <[EMAIL PROTECTED]> writes: > [EMAIL PROTECTED] wrote: > > s is not equal to the boolean object True, but it also doesn't > > evaluate to the string class's "nil" value. Each of the builtin > > types has such an "empty" or "nil" value: > > > > string "" > > list[] > > tuple () > > dict{} > > int 0 > > float 0.0 > > complex 0j > > set set() > > > > Any other value besides the above will compare as "not false". > > And today's question for the novices is: which Python type did Skip > miss from the above list? bool False -- \ "[The RIAA] have the patience to keep stomping. They're playing | `\ whack-a-mole with an infinite supply of tokens." -- kennon, | _o__) http://kuro5hin.org/ | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
George Sakkis wrote: > Martin v. Löwis wrote: >> Not-so-obviously, arbitrary user-defined values can also be >> treated as false: If they implement __nonzero__, they are >> false if False is returned from __nonzero__; otherwise, >> if they implement __len__, they are false if 0 is returned >> from __len__. Under these rules, array.array objects can >> also be false, as can UserList and UserDict objects. > > A notable exception are numarray arrays (probably true for numpy too, I > haven't tested it though): > from numarray import array bool(array([1,2])) > Traceback (most recent call last): > File "", line 1, in ? > RuntimeError: An array doesn't make sense as a truth value. Use any(a) > or all(a). numpy also has this behavior. Numeric yielded to the temptation to guess any(a) in the face of this ambiguity. Much buggy code was written as a result. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
On 2006-10-25, John Coleman <[EMAIL PROTECTED]> wrote: > > Paul Rubin wrote: >> John Salerno <[EMAIL PROTECTED]> writes: >> > I'm a little confused. Why doesn't s evaluate to True in the first >> > part, but it does in the second? Is the first statement something >> > different? >> >> No. True and False are boolean values, where booleans are a different >> data type from strings, just like strings are different from integers. >> >> >>> if s: >> print 'hi' >> >> converts s to a boolean during evaluation. That is, it's the same as >> >> if bool(s): print 'hi' >> >> bool(s) is a function that converts s to a bool. If s is a string, >> bool(s) is true if s is nonempty, false otherwise. >> >> A comparable thing with integers: suppose >> >>x = 3.1 >> >> then "x == 3" is false, but "int(x) == 3" is true. > > But then why is 3.0 == 3 true? They are different types. 3 gets promoted to a float. In most (all?) current implementations, that turns out to be 3.0, but that's not guaranteed. It could be argued that promotion of integer types to floats and shorter integers to longer integers is "a bad thing" in what's supposed to be a strictly typed language. But, it's one of those things that done that way because it's always been done that way. While it does make life simpler in many cases, it's also a source of bugs in others. -- Grant Edwards grante Yow! Why is it that when at you DIE, you can't take visi.comyour HOME ENTERTAINMENT CENTER with you?? -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Paul Rubin wrote: > John Salerno <[EMAIL PROTECTED]> writes: > >>if (10 > 5) >>would be the same as >>if (10 > 5) == True > > > Yes. Though it would be bad style to write it in the latter way, not to mention less efficient. regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John Coleman wrote: > Martin v. Löwis wrote: > >>John Coleman schrieb: >> >>>Yes - it just seems that there isn't a principled reason for implicitly >>>converting 3 to 3.0 in 3.0 == 3 but not implicitly converting "cat" to >>>boolean in "cat" == true. >> >>Sure there is: equality should be transitive. So while we have >>3 == 3L == 3.0 == 3.0+0j >>and can therefore imply that 3 == 3.0+0j, we should not get >>5 == True == ["foo"] >>and therefore imply that 5 == ["foo"]. >> >>The phenomenon really exists only for numeric types (that two >>values of different types still represent the same "thing"), >>so it's not surprising that this doesn't readily extend to >>other types. >> >>In Python, there are only very few similar cases: byte strings >>and unicode strings sometimes compare equal (but, since 2.5, >>don't compare unequal very often); lists and tuples could be >>considered to have equal values, but don't actually do compare >>equal. >> >>Regards, >>Martin > > > Very good point, though one could argue perhaps that when one is > comparing an object with a truth value then one is implicitly asking > for the truth value of that object i.e. how it would function if used > in an if statement, etc. This would make code like 'if s: ' equivalent > to 'if s == True:' with a possible gain in readability. But - as you > demonstrate the cost of that (minimal) gain in readability would be too > high. In any event - I think it is mostly bad style to use a > non-boolean variable in 'if s:' - it reminds me too much of obscure C > code (though others might disagree). > That's such a well-used (even though sometime abused) Ptyhon idiom that it's never going to go away. regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
[EMAIL PROTECTED] wrote: > John> I'm a little confused. Why doesn't s evaluate to True in the first > John> part, but it does in the second? Is the first statement something > John> different? > > >>> s = 'hello' > >>> s == True > False > >>> if s: > ... print 'hi' > hi > > s is not equal to the boolean object True, but it also doesn't evaluate to > the string class's "nil" value. Each of the builtin types has such an > "empty" or "nil" value: > > string "" > list[] > tuple () > dict{} > int 0 > float 0.0 > complex 0j > set set() > > Any other value besides the above will compare as "not false". > And today's question for the novices is: which Python type did Skip miss from the above list? regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
In article <[EMAIL PROTECTED]>, "John Coleman" <[EMAIL PROTECTED]> wrote: > Very good point, though one could argue perhaps that when one is > comparing an object with a truth value then one is implicitly asking > for the truth value of that object On the contrary -- since there is normally no need to ever compare an object with a truth value, then I would interpret this usage as an attempt to distinguish True or False from other objects in general. Some kind of placeholders for missing values, who knows. I'm not saying it's a great idea, but it could work in recent versions of Python. > This would make code like 'if s: ' equivalent > to 'if s == True:' with a possible gain in readability. But - as you > demonstrate the cost of that (minimal) gain in readability would be too > high. In any event - I think it is mostly bad style to use a > non-boolean variable in 'if s:' - it reminds me too much of obscure C > code (though others might disagree). Others will indeed disagree. I don't think you'll find much support for this position. But it's not as bad as your notion that "if s == True", where s is not a boolean object, might represent a gain in readability. That really redefines readability. Donn Cave, [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Martin v. Löwis wrote: > [EMAIL PROTECTED] schrieb: > > the string class's "nil" value. Each of the builtin types has such an > > "empty" or "nil" value: > > > > string "" > > list[] > > tuple () > > dict{} > > int 0 > > float 0.0 > > complex 0j > > set set() > > > > Any other value besides the above will compare as "not false". > > This list of values that are considered false is incomplete, > though. Four obvious omissions are > > long 0L > unicodeu"" > bool False > NoneType None > > Not-so-obviously, arbitrary user-defined values can also be > treated as false: If they implement __nonzero__, they are > false if False is returned from __nonzero__; otherwise, > if they implement __len__, they are false if 0 is returned > from __len__. Under these rules, array.array objects can > also be false, as can UserList and UserDict objects. A notable exception are numarray arrays (probably true for numpy too, I haven't tested it though): >>> from numarray import array >>> bool(array([1,2])) Traceback (most recent call last): File "", line 1, in ? RuntimeError: An array doesn't make sense as a truth value. Use any(a) or all(a). George -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Martin v. Löwis wrote: > John Coleman schrieb: > > Yes - it just seems that there isn't a principled reason for implicitly > > converting 3 to 3.0 in 3.0 == 3 but not implicitly converting "cat" to > > boolean in "cat" == true. > > Sure there is: equality should be transitive. So while we have > 3 == 3L == 3.0 == 3.0+0j > and can therefore imply that 3 == 3.0+0j, we should not get > 5 == True == ["foo"] > and therefore imply that 5 == ["foo"]. > > The phenomenon really exists only for numeric types (that two > values of different types still represent the same "thing"), > so it's not surprising that this doesn't readily extend to > other types. > > In Python, there are only very few similar cases: byte strings > and unicode strings sometimes compare equal (but, since 2.5, > don't compare unequal very often); lists and tuples could be > considered to have equal values, but don't actually do compare > equal. > > Regards, > Martin Very good point, though one could argue perhaps that when one is comparing an object with a truth value then one is implicitly asking for the truth value of that object i.e. how it would function if used in an if statement, etc. This would make code like 'if s: ' equivalent to 'if s == True:' with a possible gain in readability. But - as you demonstrate the cost of that (minimal) gain in readability would be too high. In any event - I think it is mostly bad style to use a non-boolean variable in 'if s:' - it reminds me too much of obscure C code (though others might disagree). -John Coleman -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John Coleman schrieb: > Yes - it just seems that there isn't a principled reason for implicitly > converting 3 to 3.0 in 3.0 == 3 but not implicitly converting "cat" to > boolean in "cat" == true. Sure there is: equality should be transitive. So while we have 3 == 3L == 3.0 == 3.0+0j and can therefore imply that 3 == 3.0+0j, we should not get 5 == True == ["foo"] and therefore imply that 5 == ["foo"]. The phenomenon really exists only for numeric types (that two values of different types still represent the same "thing"), so it's not surprising that this doesn't readily extend to other types. In Python, there are only very few similar cases: byte strings and unicode strings sometimes compare equal (but, since 2.5, don't compare unequal very often); lists and tuples could be considered to have equal values, but don't actually do compare equal. Regards, Martin -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
[EMAIL PROTECTED] schrieb: > the string class's "nil" value. Each of the builtin types has such an > "empty" or "nil" value: > > string "" > list[] > tuple () > dict{} > int 0 > float 0.0 > complex 0j > set set() > > Any other value besides the above will compare as "not false". This list of values that are considered false is incomplete, though. Four obvious omissions are long 0L unicodeu"" bool False NoneType None Not-so-obviously, arbitrary user-defined values can also be treated as false: If they implement __nonzero__, they are false if False is returned from __nonzero__; otherwise, if they implement __len__, they are false if 0 is returned from __len__. Under these rules, array.array objects can also be false, as can UserList and UserDict objects. Regards, Martin -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Paul Rubin wrote: > "John Coleman" <[EMAIL PROTECTED]> writes: > > > then "x == 3" is false, but "int(x) == 3" is true. > > But then why is 3.0 == 3 true? They are different types. > > The 3 gets converted to float, like when you say > > x = 3.1 + 3 > > the result is 6.1. Yes - it just seems that there isn't a principled reason for implicitly converting 3 to 3.0 in 3.0 == 3 but not implicitly converting "cat" to boolean in "cat" == true. There is something to be said about SML's rigourous approach where 3.0 = 3 isn't even allowed since it is considered ill-typed. Nevertheless, it is doubtlessly convientent to be able to compare integers and doubles directly in the natural way and there is little practical reason to compare a string with a truth value so Python's solution does have common sense on its side. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
> So I suppose > > if (10 > 5) > > would be the same as > > if (10 > 5) == True > > because (10 > 5) does evaluate to "True". Yes...and similarly, if ((10 > 5) == True) == True for the same reason...as does if (((10 > 5) == True) == True) == True as does... :*) -tkc -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Robert Kern wrote: > They are, indeed, quite different things. Finding the truth value of an > object is not the same thing as testing if the object is equal to the > object True. Yeah, I had this in the back of my mind, but I was thinking that this test would be written as if s is True And I know that one is very different from the others. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John Coleman wrote: > But then why is 3.0 == 3 true? They are different types. > Good question. Does one type get converted to the other automatically? That's all I can think of... -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John Salerno <[EMAIL PROTECTED]> writes: > if (10 > 5) > would be the same as > if (10 > 5) == True Yes. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
"John Coleman" <[EMAIL PROTECTED]> writes: > > then "x == 3" is false, but "int(x) == 3" is true. > But then why is 3.0 == 3 true? They are different types. The 3 gets converted to float, like when you say x = 3.1 + 3 the result is 6.1. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
> I'm a little confused. Why doesn't s evaluate to True in the first part, > but it does in the second? Is the first statement something different? > > >>> s = 'hello' > >>> s == True > False > >>> if s: > print 'hi' The "if s" does an implicit (yeah, I know, "explicit is better than implicit") conversion to bool, like if bool(s): And as such, you'll find that bool(s) == True You can learn more at http://docs.python.org/lib/truth.html where you'll see that it's not really exactly a bool() call, but that strings are a special case listed here. And if not, they also have a __len__ method which would return zero/non-zero in the even that strings weren't handled, making the "actual" test (if strings weren't special-cased) (s.__len__() <> 0) == True -tkc -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John Salerno wrote: > I'm a little confused. Why doesn't s evaluate to True in the first part, > but it does in the second? Is the first statement something different? > > >>> s = 'hello' > >>> s == True > False > >>> if s: > print 'hi' "true" != "True". comparing a value to another value isn't the same thing as interpreting a value in a specific context: http://docs.python.org/lib/truth.html -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John Salerno wrote: > I'm a little confused. Why doesn't s evaluate to True in the first part, > but it does in the second? Is the first statement something different? > > >>> s = 'hello' > >>> s == True > False > >>> if s: > print 'hi' > > > hi > >>> They are, indeed, quite different things. Finding the truth value of an object is not the same thing as testing if the object is equal to the object True. When people use the phrase "evaluate to True" in the context of an if: statement, they mean that the truth value of the object (found using the special method .__nonzero__()) is True, not that it is equal to True. It's a bit of an abuse on the English language, but what isn't in software? -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Paul Rubin wrote: > No. True and False are boolean values, where booleans are a different > data type from strings, just like strings are different from integers. > > >>> if s: > print 'hi' > > converts s to a boolean during evaluation. Oh!!! I get it now! I was thinking that if s was the same as if s == True because I know sometimes you can write if statements this way (though it's wordy). But what I didn't realize was that in the cases I was thinking of, 's' was an expression that evaluated to a boolean value, not an actual value of some other type! So I suppose if (10 > 5) would be the same as if (10 > 5) == True because (10 > 5) does evaluate to "True". -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
Paul Rubin wrote: > John Salerno <[EMAIL PROTECTED]> writes: > > I'm a little confused. Why doesn't s evaluate to True in the first > > part, but it does in the second? Is the first statement something > > different? > > No. True and False are boolean values, where booleans are a different > data type from strings, just like strings are different from integers. > > >>> if s: > print 'hi' > > converts s to a boolean during evaluation. That is, it's the same as > > if bool(s): print 'hi' > > bool(s) is a function that converts s to a bool. If s is a string, > bool(s) is true if s is nonempty, false otherwise. > > A comparable thing with integers: suppose > >x = 3.1 > > then "x == 3" is false, but "int(x) == 3" is true. But then why is 3.0 == 3 true? They are different types. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John Salerno wrote: > I'm a little confused. Why doesn't s evaluate to True in the first part, > but it does in the second? Is the first statement something different? > > >>> s = 'hello' > >>> s == True > False > >>> if s: > print 'hi' > > > hi > >>> > > Thanks. Excellent question! This should help: >>> s = "Hello" >>> s 'Hello' >>> bool(s) True >>> s == True False The value of s is not equal to the value of True. But, the *boolean* value of s is True, since it is not 0 or an empty string. The python 'if' statement evaluates the boolean value of the condition expression. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John Salerno <[EMAIL PROTECTED]> writes: > I'm a little confused. Why doesn't s evaluate to True in the first > part, but it does in the second? Is the first statement something > different? No. True and False are boolean values, where booleans are a different data type from strings, just like strings are different from integers. >>> if s: print 'hi' converts s to a boolean during evaluation. That is, it's the same as if bool(s): print 'hi' bool(s) is a function that converts s to a bool. If s is a string, bool(s) is true if s is nonempty, false otherwise. A comparable thing with integers: suppose x = 3.1 then "x == 3" is false, but "int(x) == 3" is true. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about True values
John> I'm a little confused. Why doesn't s evaluate to True in the first John> part, but it does in the second? Is the first statement something John> different? >>> s = 'hello' >>> s == True False >>> if s: ... print 'hi' hi s is not equal to the boolean object True, but it also doesn't evaluate to the string class's "nil" value. Each of the builtin types has such an "empty" or "nil" value: string "" list[] tuple () dict{} int 0 float 0.0 complex 0j set set() Any other value besides the above will compare as "not false". Skip -- http://mail.python.org/mailman/listinfo/python-list
question about True values
I'm a little confused. Why doesn't s evaluate to True in the first part, but it does in the second? Is the first statement something different? >>> s = 'hello' >>> s == True False >>> if s: print 'hi' hi >>> Thanks. -- http://mail.python.org/mailman/listinfo/python-list