469,916 Members | 2,338 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,916 developers. It's quick & easy.

any() and all() on empty list?

So, Python 2.5 will have new any() and all() functions.
http://www.python.org/dev/peps/pep-0356/
any(seq) returns True if any value in seq evaluates true, False otherwise.

all(seq) returns True if all values in seq evaluate true, False otherwise.

I have a question: what should these functions return when seq is an empty
list?

Here is Guido's original article where he suggested any() and all():
http://www.artima.com/weblogs/viewpost.jsp?thread=98196

He offered this sample code for the semantics of any() and all():

def any(S):
for x in S:
if x:
return True
return False

def all(S):
for x in S:
if not x:
return False
return True

And he pointed out how nifty it is to combine generator functions with
these two new functions:
any(x > 42 for x in S) # True if any elements of S are > 42
all(x != 0 for x in S) # True if all elements if S are nonzero

I'm completely on board with the semantics for any(). But all() bothers
me. If all() receives an empty list, it will return True, and I don't
like that. To me, all() should be a more restrictive function than any(),
and it bothers me to see a case where any() returns False but all()
returns True.

In the all() example, if there *are* no values in S, then none of the
values can be != 0, and IMHO all() should return False.

Therefore, I propose that all() should work as if it were written this way:

def all(S):
ret_val = False

for x in S:
ret_val = True
if not x:
return False

return ret_val
Comments?

P.S. I searched with Google, and with Google Groups, trying to find
anyplace this might have been discussed before. Apologies if this has
already been discussed and I missed it somehow.
--
Steve R. Hastings "Vita est"
st***@hastings.org http://www.blarg.net/~steveha

Mar 29 '06 #1
59 8048
"Steve R. Hastings" <st***@hastings.org> writes:
In the all() example, if there *are* no values in S, then none of the
values can be != 0, and IMHO all() should return False.


That goes against the usual meaning of "all" in, say, mathematical logic.

Usually, "for all X in S, PRED(x) is true" means:
there does not exist X in S so that PRED(x) is false.

So, all(empty sequence) should be true.
Mar 29 '06 #2
"Paul Rubin" <http://ph****@NOSPAM.invalid> wrote in message
news:7x************@ruckus.brouhaha.com...
"Steve R. Hastings" <st***@hastings.org> writes:
In the all() example, if there *are* no values in S, then none of the
values can be != 0, and IMHO all() should return False.
That goes against the usual meaning of "all" in, say, mathematical logic.

Usually, "for all X in S, PRED(x) is true" means:
there does not exist X in S so that PRED(x) is false.

How do you get this "usually" stuff? I would agree that this is usually
implemented as a short-circuited loop through the list, that breaks out at
the first False value. But I would not be quick to equate "commonality of
implementation" with "meaning".
So, all(empty sequence) should be true.

"should be"? Or "usually turns out to be"?

To my mind, the *meaning* of all() is that every element in the list asserts
True. But this is with an initial assumption that all() is False, unless I
test every value and find them to be True. Since I assume False to begin
with, I get no values in the list to contradict the assumption, and so
all([]) returns False.

It would seem that the resolution rests on which initial condition we
choose, False or True. Perhaps we should consult a more formal mathematical
resource for this.

-- Paul
"If it was so, it might be; and if it were so, it would be; but as it isn't,
it ain't. That's logic."
Mar 29 '06 #3
[Steve R. Hastings]
So, Python 2.5 will have new any() and all() functions.
http://www.python.org/dev/peps/pep-0356/
any(seq) returns True if any value in seq evaluates true, False otherwise..

all(seq) returns True if all values in seq evaluate true, False otherwise..

I have a question: what should these functions return when seq is an empty
list?
Here, from the current development trunk, is what they _do_ return:

Python 2.5a0 (trunk:43410M, Mar 28 2006, 16:42:49) ...
Type "help", "copyright", "credits" or "license" for more information.
any([]) False all([])

True
Here is Guido's original article where he suggested any() and all():
http://www.artima.com/weblogs/viewpost.jsp?thread=98196

He offered this sample code for the semantics of any() and all():

def any(S):
for x in S:
if x:
return True
return False

def all(S):
for x in S:
if not x:
return False
return True

...
|
I'm completely on board with the semantics for any(). But all() bothers
me. If all() receives an empty list, it will return True,
Yes.
and I don't like that.
Tough ;-)
To me, all() should be a more restrictive function than any(),
and it bothers me to see a case where any() returns False but all()
returns True.
There are deeper principles at work: so that endcases work out as
smoothly as possible, a "reduction" function applied to an empty
collection always arranges to return the identity element for the
reduction operation. This is the reason that sum([]) returns 0, for
example: 0 is the identity element for addition, meaning that x+0=x
for all x.

Other useful identities follow from this, and from the associativity
of most reduction operations. For example, sum(seq) = sum(seq[:i]) +
sum(seq[i:]) for any i >= 0, even if i is such that one (or both!) of
the slices on the right-hand side is empty. That wouldn't be true if
sum([]) were not 0, and arranging to make it true saves programmers
from having to deal with some otherwise special cases.

The reduction operation for any() is logical-or, and False is the
identity element for logical-or: x logical-or False = x for all
Boolean x.

Likewise the reduction operation for all() is logical-and, and True is
the identity element for that: x logical-and True = x for all Boolean
x.

Examples of other useful identities that follow from picking the
identity elements in the empty case, which hold even if `seq` is
empty:

any(seq) = not all(not x for x in seq)
all(seq) = not any(not x for x in seq)
In the all() example, if there *are* no values in S, then none of the
values can be != 0, and IMHO all() should return False.
That would break everything mentioned above. Think of it another way:
if all(seq) is false, shouldn't it be the case that you can point to
a specific element in seq that is false? After all (pun intended
;-)), if it's not the case that all x in seq are true, it must be the
case that some x in seq is false. But if seq is empty, there is no x
in seq that's either true or false, and in particular there's no x in
seq that's false. Since we can't exhibit an x in seq such that x is
false, saying that all(seq) is false would be very surprising to you
on some other day ;-)
Therefore, I propose that all() should work as if it were written this way:

def all(S):
ret_val = False

for x in S:
ret_val = True
if not x:
return False

return ret_val
Comments?


That won't happen, for three reasons: several were given above; this
is also the convention used for universal and existential quantifiers
applied to empty sets in mathematical logic (and for much the same
reasons there); and it matches prior art in the ABC language (which is
one of Python's predecessors, and which had direct syntactic support
for universal and existential quantifiers in Boolean expressions).
Mar 29 '06 #4
"Steve R. Hastings" <st***@hastings.org> writes:
So, Python 2.5 will have new any() and all() functions.
http://www.python.org/dev/peps/pep-0356/
And there was much rejoicing.
any(seq) returns True if any value in seq evaluates true, False otherwise.
Yep.
all(seq) returns True if all values in seq evaluate true, False otherwise.
Not quite how I'd phrase it. I prefer, for symmetry with 'any':

all(seq) returns False if any value in seq evaluates false, True otherwise.
I have a question: what should these functions return when seq is an
empty list?

Here is Guido's original article where he suggested any() and all():
http://www.artima.com/weblogs/viewpost.jsp?thread=98196

He offered this sample code for the semantics of any() and all():

def any(S):
for x in S:
if x:
return True
return False

def all(S):
for x in S:
if not x:
return False
return True
I love the symmetry of these semantics, find them quite intuitive, and
therefore disagree with your interpretation of 'all()'.
I'm completely on board with the semantics for any(). But all() bothers
me. If all() receives an empty list, it will return True, and I don't
like that. To me, all() should be a more restrictive function than any(),
and it bothers me to see a case where any() returns False but all()
returns True.


-1.

You may as well argue that "any() should be a more restrictive
function than all(), and it bothers me to see a case where all()
returns False but any() returns True."
It seems clear to me that an empty argument list fails a check for
"any True?", because that's the same as a check for "all False?". The
only reasonable alternative would be a special case for an empty
argument list, and that's too ugly.

It seems clear to me that an empty argument list passes a check for
"all True?", because that's the same as a check for "any False?". The
only reasonable alternative would be a special case for an empty
argument list, and that's too ugly.

To imagine that one of these "should be a more restrictive function"
would belie their simple, elegant, and (to me) obvious definitions. I
disagree with your interpretation.

--
\ "My house is made out of balsa wood, so when I want to scare |
`\ the neighborhood kids I lift it over my head and tell them to |
_o__) get out of my yard or I'll throw it at them." -- Steven Wright |
Ben Finney

Mar 29 '06 #5
"Steve R. Hastings" <st***@hastings.org> wrote in message
news:pa****************************@hastings.org.. .
So, Python 2.5 will have new any() and all() functions.
http://www.python.org/dev/peps/pep-0356/
any(seq) returns True if any value in seq evaluates true, False otherwise.

all(seq) returns True if all values in seq evaluate true, False otherwise.

I have a question: what should these functions return when seq is an empty
list?

Here is my attempt at a more formal approach to this question, rather than
just using our intuition. Unfortunately, following this process proves my
earlier post to be wrong, but, oh well...

Consider two sets A and B where A+B is the union of the two sets.

if any(A+B) = True -> any(A) or any(B) = True
but we cannot assert either any(A)=True or any(B)=True.

if any(A+B) = False -> any(A) = False and any(B) = False.
if all(A+B) = True -> all(A)=True and all(B)=True
if all(A+B) = False -> all(A)=False or all(B)=False
but we cannot assert either all(A)=False or all(B)=False.
Now instead of B, lets add the empty set 0 to A. We want to come up logic
such that adding the empty set does not change the values of all() or any(),
since A+0=A.

any(A+0) = any(A) or any(0)

any(0) must be False, so that if any(A) is True, any(A+0) is True, and if
any(A) is False, any(A+0) is False.

all(A+0) = all(A) and all(0)

if all(A) is True, all(A+0) is True.
Therefore, all(0) is True.

-- Paul
Mar 29 '06 #6
Thank you very much for explaining this. And so thoroughly!

Of course I withdraw all objections. :-)
--
Steve R. Hastings "Vita est"
st***@hastings.org http://www.blarg.net/~steveha

Mar 29 '06 #7
"Paul McGuire" <pt***@austin.rr._bogus_.com> writes:
Usually, "for all X in S, PRED(x) is true" means:
there does not exist X in S so that PRED(x) is false.

How do you get this "usually" stuff? I would agree that this is usually
implemented as a short-circuited loop through the list, that breaks out at
the first False value. But I would not be quick to equate "commonality of
implementation" with "meaning".


See <http://en.wikipedia.org/wiki/For_all>:

Generally, then, the negation of a propositional function's universal
quantification is an existential quantification of that propositional
function's negation; symbolically,

\lnot\ \forall{x}{\in}\mathbf{X}\, P(x) \equiv\
\exists{x}{\in}\mathbf{X}\, \lnot\ P(x)
Mar 29 '06 #8
Paul McGuire enlightened us with:
That goes against the usual meaning of "all" in, say, mathematical
logic.

Usually, "for all X in S, PRED(x) is true" means: there does not
exist X in S so that PRED(x) is false.
How do you get this "usually" stuff?


From its mathematical definition.
I would agree that this is usually implemented as a short-circuited
loop through the list, that breaks out at the first False value.
Implementation is irrelevant when it comes to the definition of a
mathematical operator.
But I would not be quick to equate "commonality of implementation"
with "meaning".
Which is good.
Perhaps we should consult a more formal mathematical resource for
this.


In mathematics, 'for all x in A, f(x) is True' is true when A is
empty. You can either look it up on trust someone who studied
mathematics (me) on it.

Sybren
--
The problem with the world is stupidity. Not saying there should be a
capital punishment for stupidity, but why don't we just take the
safety labels off of everything and let the problem solve itself?
Frank Zappa
Mar 29 '06 #9
Paul McGuire wrote:
"Paul Rubin" <http://ph****@NOSPAM.invalid> wrote in message
news:7x************@ruckus.brouhaha.com... To my mind, the *meaning* of all() is that every element in the list asserts
True. But this is with an initial assumption that all() is False, unless I
test every value and find them to be True. Since I assume False to begin
with, I get no values in the list to contradict the assumption, and so
all([]) returns False.


Looking at in a different way... If we consider also having a function
none() (for comparison), would it be consistent with all()?

def none(S):
for x in S:
if x: return False
return True
any([]) -> False

none([]) -> True (same as 'not any(S)')

all([]) -> True ? False
I think I agree that all() should have an initial presumption of being
False.
Looking at it in yet another way... (yes, not as efficient)

def all(S):
S_ = [x for x in S if x]
return S_ == S

def any(S):
S_ = [x for x in S if x]
return S_ != []

def none(S):
S_ = [x for x in S if x]
return S_ == []
In this view and empty set can be True for all(). Is it posible
'all([])' is undefined? Here, none() and all() return contradicting
values. So maybe the correct version may be...

def all(S):
if S == []: return False
for x in S:
if x return True
return False

I think a few valid actual use case examples could clear it up. What
makes the most sense?

Cheers,
Ron

Mar 29 '06 #10
Ron Adam <rr*@ronadam.com> writes:
In this view and empty set can be True for all(). Is it posible
'all([])' is undefined? Here, none() and all() return contradicting
values. So maybe the correct version may be...


I don't see any contradiction. all([]) and none([]) are both true.

Anyway, this has all been discussed before in a slightly different context:

Harary, F. and Read, R. "Is the Null Graph a Pointless Concept?" In
Springer Lecture Notes in Math. 406 (1974) 37-44
Mar 29 '06 #11
> I'm completely on board with the semantics for any(). But all() bothers
me. If all() receives an empty list, it will return True, and I don't
like that. To me, all() should be a more restrictive function than any(),
and it bothers me to see a case where any() returns False but all()
returns True.


Who should we call to report this fallacy? GvR? Goedel? Tarski? no,
wait... Frege ! or wait... actually, I think that must be Aristotle.
Sorry Aristotle, the ol' syllogisms have to go.

; -)
All silliness aside, the meaning of all() in python corresponds just
fine with "all" in both language and logic.
s.

Mar 29 '06 #12
Paul Rubin wrote:
Ron Adam <rr*@ronadam.com> writes:
In this view and empty set can be True for all(). Is it posible
'all([])' is undefined? Here, none() and all() return contradicting
values. So maybe the correct version may be...
I don't see any contradiction. all([]) and none([]) are both true.


Contradicting wasn't the correct term to use I suppose. And in any case
it's not really the point at hand. See below.

Anyway, this has all been discussed before in a slightly different context:


I'm sure it has. And I don't mean to disagree with the pure
mathematical or logical meanings.

I'm thinking more in terms of weather or not they are defined correctly
for their desired usage. If they are meant to be used as pure logic
functions in math formulas then of course they should follow the
mathematical definitions. But if they are meant to be used as flow
control tests, then they should follow pythons flow control semantics
and do what give the best results when used as flow control tests in
most situations.

Currently:

not not [] -> False -> has None
not not [...] -> True -> has Some
So using the same semantics... (With no conditional statements)

# has any True
def any(S):
result = not not []
for x in S:
result = result or x
return not not result

# has all True
def all(S):
result = not not S
for x in S:
result = result and x
return not not result

These are 'has any True' and 'has all True' which aren't the same as the
math operations 'any True' and 'all True'.

But the real questions is, does it do the right thing in real code?

Wouldn't I want to skip a block if the sequence is an empty set?

while all(S):
...

Would I need to prefix some or many tests with a condition or logical
check for an empty set?

if S and all(S): foo()

How often would these situations come up?

Could pure logic functions 'anytrue()' and 'alltrue()' live in the math
module and 'any()' and 'all()' be flow control tests as builtins?

(Only if there is desire and need for both of course.)

Just thinking about things. I really just want what is best for Python
in the long term and am not trying to be difficult. I haven't seen
many use cases yet and it seems to me it may make a difference. So I'm
going to try to find places in my own code where these will be useful in
the meantime.

Cheers,
Ron






Mar 29 '06 #13
Ron Adam <rr*@ronadam.com> writes:
Just thinking about things. I really just want what is best for
Python in the long term and am not trying to be difficult.


I'm sorry, maybe it's the math geek in me, but I just see all those
suggestions about "not not S" as being contorted. It's obvious to me
that all([]) should be True, that while(any(S)) should not terminate
if S is empty, etc.

Someone asked for a cite; I listed one before:

http://en.wikipedia.org/wiki/For_all

See the "Negation" section.
Mar 29 '06 #14
Steve R. Hastings wrote:
I'm completely on board with the semantics for any(). But all() bothers
me. If all() receives an empty list, it will return True, and I don't
like that. To me, all() should be a more restrictive function than any(),
and it bothers me to see a case where any() returns False but all()
returns True.


Perhaps a practical example will illustrate why all() returns False
better than all this mathematical mumbo-jumbo.

Ok, say you're writing a simple software management/bug tracking
system. It manage another software package that is to have periodic
releases, but the release can only be made when there are no
outstanding bugs. You might have a line of code that looks like this:

if all(bug.status == 'closed' for bug in bugs_filed):
do_release()

As you can see, the release will only happen if all the bugs are marked
closed. But... what if no bugs have been filed? If all() were to
return False on an empty sequence, the software couldn't be fixed until
at least one bug had been filed and closed!

The point is, whenever you have to test that every item in a list is
true, it is almost always correct for the test to pass when the list is
empty. The behavior of all() is correct.
Carl Banks

Mar 29 '06 #15
At risk of flogging a dead horse...

On Wed, 29 Mar 2006 01:01:00 -0800, vdrab wrote:
I'm completely on board with the semantics for any(). But all() bothers
me. If all() receives an empty list, it will return True, and I don't
like that. To me, all() should be a more restrictive function than any(),
and it bothers me to see a case where any() returns False but all()
returns True.


Who should we call to report this fallacy? GvR? Goedel? Tarski? no,
wait... Frege ! or wait... actually, I think that must be Aristotle.
Sorry Aristotle, the ol' syllogisms have to go.

; -)
All silliness aside, the meaning of all() in python corresponds just
fine with "all" in both language and logic.
s.


(Dis)proof by counter-example:

GvR is in deep trouble -- the police now have sufficient evidence of his
guilt to lock him away for life for all of the terrorist attacks he is
suspected of:
def enough_evidence(crime): .... return True
.... suspected_attacks = []
sufficient_proof = filter(enough_evidence, suspected_attacks)
guilty = all(sufficient_proof)
if guilty: .... print "Send him to Gitmo!"
....
Send him to Gitmo!
I understand and accept Tim Peter's explanation for why the proposed
behaviour is the Right Way to handle all() and any() -- but that doesn't
mean that there isn't a paradox buried in there.

Notice that the police, by setting themselves the more difficult task of
proving Guido's guilt on all() charges, can lock him up even though no
crime was committed. Whereas, if they took the simpler task of merely
proving his guilt on any() charge, Guido would be a free man:
guilty = any(sufficient_proof)
if not guilty:

.... print "Walk free!"
....
Walk free!
While the implemented behaviour might be more practical than the
alternatives, it is still worrying paradoxical. If "All sheep are woolly",
then obviously it must also be true that "Any sheep is woolly". More
formally, if all(X), then any(X) -- except for the case of empty X. Hmmm.

--
Steven.

Mar 29 '06 #16
Steven D'Aprano <st***@REMOVETHIScyber.com.au> writes:
While the implemented behaviour might be more practical than the
alternatives, it is still worrying paradoxical. If "All sheep are woolly",
then obviously it must also be true that "Any sheep is woolly". More
formally, if all(X), then any(X) -- except for the case of empty X. Hmmm.


Maybe "any" should be renamed to "some".
Mar 29 '06 #17
On Wed, 29 Mar 2006 21:34:08 +1000, Steven D'Aprano wrote:
While the implemented behaviour might be more practical than the
alternatives, it is still worrying paradoxical. If "All sheep are woolly",
then obviously it must also be true that "Any sheep is woolly". More
formally, if all(X), then any(X) -- except for the case of empty X. Hmmm.


It seems strange, but Tim Peters explained it well. It would also seem
strange if this didn't work:

all(lst0) and all(lst1) == all(lst0 + lst1)

Clearly that should work, and it shouldn't fail just because one of the
lists happens to be empty.

If you are working with a list, you can just do this:

lst and all(lst)

What bothers me is the iterator case. There is no simple way to write a
test like the above if you have an iterator.

Hmmm. How about this?
def truecount(seq):
count_true = 0
count= 0
for x in seq:
if x:
count_true += 1
count += 1
return count_true, count

count_true, count = truecount(enough_evidence(x) for x in suspected_attacks)
if not count:
print "Walk free!"
elif count == count_true:
print "Send him to Gitmo!"
else:
print "%d proven attacks out of %d suspected" % (count_true, count)
if float(count_true) / float(count) >= 0.8:
print "preponderance of evidence!"

The good thing is that these are simple functions that you can write for
yourself. I'm happy any() and all() will be built in, but I don't know
that there is sufficient need for truecount() or anything similar. If you
need it, just write it.
--
Steve R. Hastings "Vita est"
st***@hastings.org http://www.blarg.net/~steveha

Mar 29 '06 #18
Paul Rubin wrote:
Ron Adam <rr*@ronadam.com> writes:
Just thinking about things. I really just want what is best for
Python in the long term and am not trying to be difficult.
I'm sorry, maybe it's the math geek in me, but I just see all those
suggestions about "not not S" as being contorted. It's obvious to me
that all([]) should be True, that while(any(S)) should not terminate
if S is empty, etc.


The 'not not S' is just a conversion to bool. Is the following less
contorted to you?
bool([])

False
Someone asked for a cite; I listed one before:

http://en.wikipedia.org/wiki/For_all

See the "Negation" section.

'Is all True' isn't the same as 'Has all True'. As I said, I'm not
questioning the mathematical meaning of the set relation 'is all True',
but wondering weather or not an alternate relation 'has all True' would
be better for use as a flow control test.
Do you have some examples uses since it's obvious to you?

We could all probably come up with examples that support either side.
What I'm looking for are the obvious and common use examples. How would
they behave differently depending on weather 'is all true' or 'has all
true' is used? Which would be faster and simpler to use in most cases.

I just have a feeling we will see a lot of "S and all(S)" expressions
being used. Maybe that's not so bad, but I would prefer to not have to
do that if it turns out to the standard idiom for all testing within a loop.
The actual code used would be more efficient than my examples, they will
have shortcutting behavior, and written in C. Those examples where
meant to show the principle.

And the question still stands:

"Does it do the right thing in most situations it will be used in?"
That will of course depend on weather it's being used as a mathematics
test, or for flow control test. Which is why I suggested the possibly
of having both. I believe the flow control semantics will be the more
common use, but I may be mistaken thinking "S and all(S)" will be needed
in most cases.

<shrug>This doesn't seem to be an issue for anyone else, so I'll wait
and see how it turns out.

Cheers,
Ron

Mar 30 '06 #19
Carl Banks wrote:
Steve R. Hastings wrote:
I'm completely on board with the semantics for any(). But all() bothers
me. If all() receives an empty list, it will return True, and I don't
like that. To me, all() should be a more restrictive function than any(),
and it bothers me to see a case where any() returns False but all()
returns True.


Perhaps a practical example will illustrate why all() returns False
better than all this mathematical mumbo-jumbo.

Ok, say you're writing a simple software management/bug tracking
system. It manage another software package that is to have periodic
releases, but the release can only be made when there are no
outstanding bugs. You might have a line of code that looks like this:

if all(bug.status == 'closed' for bug in bugs_filed):
do_release()

As you can see, the release will only happen if all the bugs are marked
closed. But... what if no bugs have been filed? If all() were to
return False on an empty sequence, the software couldn't be fixed until
at least one bug had been filed and closed!

The point is, whenever you have to test that every item in a list is
true, it is almost always correct for the test to pass when the list is
empty. The behavior of all() is correct.
Carl Banks

Yes, But that should be a test for 'not any()'.

if not any(bug.status == 'open' for bug in bugs_filed):
do_release()
So to give a counter example...

Where we are assembling widgets in a manufacturing plant. Where we don't
want to go to the next step until *all* the sub parts are present.

if all(part.status == 'present' for part in unit):
do_release()

Oops! Some empty bins showed up at the next assembly station. ;-)
Cheers,
Ron

Mar 30 '06 #20
Ron Adam wrote:
Where we are assembling widgets in a manufacturing plant. Where we don't
want to go to the next step until *all* the sub parts are present.

if all(part.status == 'present' for part in unit):
do_release()

Oops! Some empty bins showed up at the next assembly station. ;-)


I don't see the problem. You only get an empty bin if there is some part
assembled from no sub-parts, in which case you wanted an empty bin.
Mar 30 '06 #21
Tim Peters wrote:
In the all() example, if there *are* no values in S, then none of the
values can be != 0, and IMHO all() should return False.

That would break everything mentioned above. Think of it another way:
if all(seq) is false, shouldn't it be the case that you can point to
a specific element in seq that is false?


Think of it this way: if all(seq) is true, shouldn't it
be the case that you can point to a specific element in
seq that is true?

It may be that all([]) => True is useful more often
than all([]) => False would be, in the same way that it
is useful to define 0! = 1 and other mathematical
identities, but that doesn't imply that, strictly
speaking, there isn't some monkey-business going on there.

Now, I'm happy to admit that this is useful
monkey-business, but it can still lead to unexpected
results, as in my example in a previous post.

--
Steven.

Mar 30 '06 #22
Steven D'Aprano <st***@REMOVEMEcyber.com.au> writes:
Think of it this way: if all(seq) is true, shouldn't it be the case
that you can point to a specific element in seq that is true?


No, all(seq) is true if you can't point to a specific element in seq
that's false.
Mar 30 '06 #23
Paul Rubin wrote:
Steven D'Aprano <st***@REMOVEMEcyber.com.au> writes:
Think of it this way: if all(seq) is true, shouldn't it be the case
that you can point to a specific element in seq that is true?

No, all(seq) is true if you can't point to a specific element in seq
that's false.


No, all(seq) is true if every element in seq is true.
Surely that's a more intuitive definition than your
definition by what you can't do.

The question that needs to be answered is, what if
there are no elements at all? That's an arbitrary
decision. Like the question "what is 0**0?" in
mathematics, some answers are more useful than others.
I can respect that practical answer -- but it isn't the
*only* answer.

(For those who don't see why 0**0 is problematic, 0**x
is equal to 0 for all x, and x**0 is equal to 1 for all
x, so what do you do for 0**0?)

Here's another way of looking at the problem:

all(flying elephants which are pink) => true
all(flying elephants which are not pink) => true

So, these flying elephants -- are they pink or not?

--
Steven.

Mar 30 '06 #24
Duncan Booth wrote:
Ron Adam wrote:

Where we are assembling widgets in a manufacturing plant. Where we don't
want to go to the next step until *all* the sub parts are present.

if all(part.status == 'present' for part in unit):
do_release()

Oops! Some empty bins showed up at the next assembly station. ;-)

I don't see the problem. You only get an empty bin if there is some part
assembled from no sub-parts, in which case you wanted an empty bin.


Okay, Ron's example wasn't the best. How about this
one, from chess:

The intention is to play cautiously if all threatened
pieces are valuable, and daringly otherwise. Here is
the obvious, but wrong, code:

if all(piece.value() > 5 for piece in \
threatened_pieces):
play_cautiously()
else:
play_daringly()

It is wrong because it leads to incorrect behaviour
when there are no threatened pieces at all -- the
intention is to play daringly by default, except for
the specific case of there being threatened pieces, all
of which are high value pieces.

So one correct, but more verbose, way to code this
would be:

valuable_danger = [piece.value() > 5 for piece in \
threatened_pieces]
if valuable_danger and all(valuable_danger):
play_cautiously()
else:
play_daringly()
Another obvious way of coding this would be to reverse
the sign of the test like so:

if not any(piece.value() <= 5 for piece in \
threatened_pieces):
play_cautiously()
else:
play_daringly()

In other words, play daringly unless no threatened
piece is low value. Unfortunately, while this is
obvious, it also gives the wrong behaviour when there
are no threatened pieces.

The lesson of this example is that while the standard
behaviour of any() and all(), as implemented in Python,
are often, usually, the Right Way to do things, they do
fail on some occasions, and coders should be aware of
cases where the assumptions break down.
--
Steven.

Mar 30 '06 #25

Steven D'Aprano wrote:
Paul Rubin wrote:
Steven D'Aprano <st***@REMOVEMEcyber.com.au> writes:
Think of it this way: if all(seq) is true, shouldn't it be the case
that you can point to a specific element in seq that is true?

No, all(seq) is true if you can't point to a specific element in seq
that's false.


No, all(seq) is true if every element in seq is true.
Surely that's a more intuitive definition than your
definition by what you can't do.

The question that needs to be answered is, what if
there are no elements at all?


Then every element in seq is true.

(And false. :)
Carl Banks

Mar 30 '06 #26
Steven D'Aprano wrote:
Okay, Ron's example wasn't the best. How about this
one, from chess:

The intention is to play cautiously if all threatened
pieces are valuable, and daringly otherwise.


Isn't that example even worse? Compare:

- You have one of your valuable pieces threatened. You decide to play
cautiously.

- You have one valuable and one piece of lesser value threatened. You play
daringly.

What is that? The courage of despair?

if any(piece.value > 5 for piece in threatened):
# play cautiously
else:
# play daringly

looks more convincing to the non-chessplaying bystander (read: me) and --
surprise -- is supported by the new builtins just fine.

Peter
Mar 30 '06 #27
Steven D'Aprano wrote:
Paul Rubin wrote:
Steven D'Aprano <st***@REMOVEMEcyber.com.au> writes:
Think of it this way: if all(seq) is true, shouldn't it be the case
that you can point to a specific element in seq that is true?

No, all(seq) is true if you can't point to a specific element in seq
that's false.


No, all(seq) is true if every element in seq is true.
Surely that's a more intuitive definition than your
definition by what you can't do.

The question that needs to be answered is, what if
there are no elements at all? That's an arbitrary
decision. Like the question "what is 0**0?" in
mathematics, some answers are more useful than others.
I can respect that practical answer -- but it isn't the
*only* answer.

(For those who don't see why 0**0 is problematic, 0**x
is equal to 0 for all x, and x**0 is equal to 1 for all
x, so what do you do for 0**0?)

Here's another way of looking at the problem:

all(flying elephants which are pink) => true
all(flying elephants which are not pink) => true

So, these flying elephants -- are they pink or not?


No, you ask two different sets whether they are true.

Georg
Mar 30 '06 #28
Duncan Booth wrote:
Ron Adam wrote:
Where we are assembling widgets in a manufacturing plant. Where we don't
want to go to the next step until *all* the sub parts are present.

if all(part.status == 'present' for part in unit):
do_release()

Oops! Some empty bins showed up at the next assembly station. ;-)


I don't see the problem. You only get an empty bin if there is some part
assembled from no sub-parts, in which case you wanted an empty bin.


Hmmm... It wasn't a well though out example. I was thinking in terms
of several processes working at the same time, and not communicating
with each other. Ie.. a bin getter, a part inserter, a part checker, a
bin mover. etc.

But even then if all the parts get marked as 'present' even though they
are aren't there, the bin could be released to the next station. And so
that example is void. I'll try and think of a better one.
Cheers,
Ron

Mar 30 '06 #29
Steven D'Aprano wrote:
Paul Rubin wrote:
Steven D'Aprano <st***@REMOVEMEcyber.com.au> writes:
Think of it this way: if all(seq) is true, shouldn't it be the case
that you can point to a specific element in seq that is true?

No, all(seq) is true if you can't point to a specific element in seq
that's false.


No, all(seq) is true if every element in seq is true. Surely that's a
more intuitive definition than your definition by what you can't do.

Yes, they are both valid view points. One is 'is all true' and the
other is 'has all true'.

You can also use either to express the other...

S and isalltrue(S) -> hasalltrue(S)

not S or hasalltrue(S) -> isalltrue(S)

A possibly useful thing to have:

hasall(S, value, test=None)

hasall(S, True) # Test for actual "True" values or 1.
hasall(S, True, bool) # test for true values, not zero or False.
hasall(S, 'ok')
hasall(S, True, lambda n: n=42)

Cheers,
Ron



Mar 30 '06 #30
Ron Adam wrote:

hasall(S, True, lambda n: n=42)


That was suppose to be:

hasall(S, True, lambda n: n==42)
Mar 30 '06 #31
Georg Brandl wrote:
Steven D'Aprano wrote:
all(flying elephants which are pink) => true
all(flying elephants which are not pink) => true

So, these flying elephants -- are they pink or not?


No, you ask two different sets whether they are true.


No, there is only one empty set.
Relevant to this discussion is stuff
about syllogisms concerning non-existent objects
and what C.S. Peirce did to them in the 19th century.
See e.g. http://www.math.fau.edu/schonbek/mfl....html#tth_sEc5
Marcin
Mar 30 '06 #32
Marcin Ciura wrote:
all(flying elephants which are not pink) => true

So, these flying elephants -- are they pink or not?


No, you ask two different sets whether they are true.


No, there is only one empty set.


who said anything about empty sets ?

</F>

Mar 30 '06 #33
Op 2006-03-30, Steven D'Aprano schreef <st***@REMOVEMEcyber.com.au>:
Paul Rubin wrote:
Steven D'Aprano <st***@REMOVEMEcyber.com.au> writes:
Think of it this way: if all(seq) is true, shouldn't it be the case
that you can point to a specific element in seq that is true?

No, all(seq) is true if you can't point to a specific element in seq
that's false.


No, all(seq) is true if every element in seq is true.
Surely that's a more intuitive definition than your
definition by what you can't do.

The question that needs to be answered is, what if
there are no elements at all? That's an arbitrary
decision. Like the question "what is 0**0?" in
mathematics, some answers are more useful than others.
I can respect that practical answer -- but it isn't the
*only* answer.

(For those who don't see why 0**0 is problematic, 0**x
is equal to 0 for all x, and x**0 is equal to 1 for all
x, so what do you do for 0**0?)

Here's another way of looking at the problem:

all(flying elephants which are pink) => true
all(flying elephants which are not pink) => true

So, these flying elephants -- are they pink or not?


They are both.

--
Antoon Pardon
Mar 30 '06 #34

"Antoon Pardon" <ap*****@forel.vub.ac.be> wrote in message
news:sl********************@rcpc42.vub.ac.be...
Op 2006-03-30, Steven D'Aprano schreef <st***@REMOVEMEcyber.com.au>:
So, these flying elephants -- are they pink or not?


They are both.


That would make them Schrödinger elephants!

-- Paul
Mar 30 '06 #35
Steven D'Aprano <st***@REMOVEMEcyber.com.au> writes:
No, all(seq) is true if you can't point to a specific element in seq
that's false.
No, all(seq) is true if every element in seq is true. Surely that's a
more intuitive definition than your definition by what you can't do.


They are different? I'd say every element in seq is true, unless
there's an element that's false. Do you want to pick a different word
than "all" and suggest renaming the function?
Here's another way of looking at the problem:

all(flying elephants which are pink) => true
all(flying elephants which are not pink) => true

So, these flying elephants -- are they pink or not?


By the definition, "all flying elephants are pink" and "all flying
elephants are non-pink" are both true statements, if that's what
you're asking. There is no contradiction. It's one of those
questions like "have you stopped beating your wife".

I'd say:

def boolify(s): return map(bool, s)

then:

all(S) = reduce(operator.and_, boolify(S), True)
any(S) = reduce(operator.or_, boolify(S), False)

You can see that changing True to False in the above definition of all
would make the result always false.

FWIW, I threw all my TV sets off the roof of my building this morning.
But nobody on the sidewalk needed to worry about getting hit by one ;-).
Mar 30 '06 #36
On Thu, 30 Mar 2006 11:28:54 -0800, Paul Rubin wrote:
Steven D'Aprano <st***@REMOVEMEcyber.com.au> writes:
> No, all(seq) is true if you can't point to a specific element in seq
> that's false.
No, all(seq) is true if every element in seq is true. Surely that's a
more intuitive definition than your definition by what you can't do.


They are different?


Of course they are different -- they differ in the case of an empty
sequence.
I'd say every element in seq is true, unless
there's an element that's false. Do you want to pick a different word
than "all" and suggest renaming the function?
I've already pointed out that I'm satisfied with Tim Peters' explanation
for why the defined behaviour for any() is *most often* the Right Way for
it to be implemented in Python, *but* there are circumstances that this
behaviour is incorrect, therefore the programmer needs to actually
consider carefully what should happen for the empty sequence case. Was I
not clear enough?
Here's another way of looking at the problem:

all(flying elephants which are pink) => true
all(flying elephants which are not pink) => true

So, these flying elephants -- are they pink or not?


By the definition, "all flying elephants are pink" and "all flying
elephants are non-pink" are both true statements, if that's what
you're asking. There is no contradiction.


Of course there is a contradiction. The contradiction is that flying
elephants are simultaneously pink and not pink.

If you don't understand why "Foo is Bar" and "Foo is not Bar" can't both
be true simultaneously, I suggest you spend some time googling on
"noncontradiction logic". To get you started, here's the Wikipedia entry:

http://en.wikipedia.org/wiki/Law_of_noncontradiction

It's one of those
questions like "have you stopped beating your wife".


Think about it: what is the logical value of the boolean "I have stopped
beating my wife" in the case of somebody who never started beating
their wife?

if husband.stopped_beating_wife(): # returns True or False
pay_fine()
else:
go_to_jail()

Pretty hard on the innocent husbands who never even beat their wife at all.

What we're doing is running up to the limitations of Aristotelian
two-value logic. We're trying to pigeon-hole answers into True/False that
really don't fit, so of course there will be the occasional case where
neither True nor False is correct. In hacker culture, the Chinese word
"mu" (literally "without") is sometimes used to mean "I cannot answer that
question because your assumptions are not correct".

In the case of all(seq), the correct answer is "mu". But since we're
stuck with binary logic, the more commonly useful behaviour is True, but
sometimes that leads to problems, such as in my first example of Guido
being punished because he was found guilty of all the terrorist crimes he
committed -- which is an empty list.
--
Steven.

Mar 30 '06 #37
Steven D'Aprano <st***@REMOVETHIScyber.com.au> writes:
No, all(seq) is true if every element in seq is true. Surely that's a
more intuitive definition than your definition by what you can't do. They are different?

Of course they are different -- they differ in the case of an empty
sequence.


I don't think they differ in the case of an empty sequence. If the
sequence is empty, both statements are true.
By the definition, "all flying elephants are pink" and "all flying
elephants are non-pink" are both true statements, if that's what
you're asking. There is no contradiction.


Of course there is a contradiction. The contradiction is that flying
elephants are simultaneously pink and not pink.


Neither statement asserts the existence of any flying elephants
regardless of color, so neither statement contradicts the other
statement.
If you don't understand why "Foo is Bar" and "Foo is not Bar" can't both
be true simultaneously, I suggest you spend some time googling on
"noncontradiction logic". To get you started, here's the Wikipedia entry:

http://en.wikipedia.org/wiki/Law_of_noncontradiction
"All flying elephants are pink" is not a statement of the form "Foo is
Bar". See <http://en.wikipedia.org/wiki/For_all>, as I've cited
several times. "All flying elephants are pink" simply means "there
are no non-pink flying elephants". "All flying elephants are
non-pink" similarly means "there are no pink flying elephants". The
statements don't contradict, and in fact both statements are true.
if husband.stopped_beating_wife(): # returns True or False
pay_fine()
else:
go_to_jail()

Pretty hard on the innocent husbands who never even beat their wife at all.
Correct. The code should not be written that way.
In hacker culture, the Chinese word
"mu" (literally "without") is sometimes used to mean "I cannot answer that
question because your assumptions are not correct".

In the case of all(seq), the correct answer is "mu".


I don't think it's that bad. We just have to spell out precisely what
the assumptions are, and we've done so.
Mar 30 '06 #38
Steven D'Aprano wrote:
On Thu, 30 Mar 2006 11:28:54 -0800, Paul Rubin wrote:
Steven D'Aprano <st***@REMOVEMEcyber.com.au> writes:
> No, all(seq) is true if you can't point to a specific element in seq
> that's false.

No, all(seq) is true if every element in seq is true. Surely that's a
more intuitive definition than your definition by what you can't do.


They are different?


Of course they are different -- they differ in the case of an empty
sequence.


No, they're not.

Look, there are significant differences between natural and computer
languages, and in this case something is happening in the natural
language that isn't happening in this computer language.

In English, if I were to ask you a question like "Have you put all your
books in the truck?" when you have no books, a valid and reasonable
answer is "I don't have any books." I.e., the answer is neither yes
nor no. In fact, yes and no aren't valid answers at all (unless you're
being snarky**), because, in English, the word "all" carries an
assumption of existence. (Or maybe it doesn't for you guys in
Australia; it does in the USA.)

In Python, yes and no are the only possible answers. Probably the only
analogous thing you could do in Python would be for all() to raise
ValueError when passed an empty sequence.
Carl Banks

** - and note that, if you are being snarky, you would say "yes".

Mar 31 '06 #39
Fredrik Lundh <fr*****@pythonware.com> wrote:
Marcin Ciura wrote:
all(flying elephants which are not pink) => true

So, these flying elephants -- are they pink or not?

No, you ask two different sets whether they are true.


No, there is only one empty set.


who said anything about empty sets ?


Universally-false predicate <--> empty set

....in Cantor's/Frege's world, which is commonly accepted as equivalent
to Aristotle's Logic. Modal logic is a different kettle of fish (and,
in retrospect, what Dodgson [aka Carroll] was groping towards)... but I
know of no programming paradigm based on it (even Turing's and Church's
map more easily to naive set theory//logic, give or take a Zermelo or
so;-). I would in fact challenge the assertion that a useful programming
paradigm COULD be based on modal logic, hoping for proof of the
contrary;-)
Alex
Mar 31 '06 #40
Carl Banks wrote:
In Python, yes and no are the only possible answers. Probably the only
analogous thing you could do in Python would be for all() to raise
ValueError when passed an empty sequence.


There is also 'None' which serves a similar purpose of indicating an
invalid value when passing arguments.

Cheers,
Ron
Mar 31 '06 #41
Alex Martelli wrote:
>>all(flying elephants which are not pink) => true
>>
>>So, these flying elephants -- are they pink or not?
>
> No, you ask two different sets whether they are true.

No, there is only one empty set.


who said anything about empty sets ?


Universally-false predicate <--> empty set

...in Cantor's/Frege's world


I was more thinking of Disney.

</F>

Mar 31 '06 #42
Op 2006-03-30, Paul McGuire schreef <pt***@austin.rr._bogus_.com>:

"Antoon Pardon" <ap*****@forel.vub.ac.be> wrote in message
news:sl********************@rcpc42.vub.ac.be...
Op 2006-03-30, Steven D'Aprano schreef <st***@REMOVEMEcyber.com.au>:
> So, these flying elephants -- are they pink or not?


They are both.


That would make them Schrödinger elephants!


Every member of the empty set is a Schrödinger element.

--
Antoon Pardon
Mar 31 '06 #43
Ant
I don't think that there will be any valid examples.

all(list) simply means "every element of the list evaluates to True".
This is trivially true in the case of the empty list. This is logically
equivalent to "There are no elements in the list which evaluate to
False".

any(list) simply means "at least one element of the list evaluates to
true". This is trivially false for the empty list - there are no
elements to be true.

These are logical functions and should be mathematically sound. It's
possible to add all sorts of problems if we just arbitrarily decide
what "for all x" should mean. We may just as well decide that for
convenience: math.pi == 3.

--
Ant...

Mar 31 '06 #44
Steve R. Hastings wrote:
Therefore, I propose that all() should work as if it were written this way: def all(S):
ret_val = False

for x in S:
ret_val = True
if not x:
return False

return ret_val

Comments?
Ant wrote:
all(list) simply means "every element of the list evaluates to True".
This is trivially true in the case of the empty list. This is logically
equivalent to "There are no elements in the list which evaluate to
False".

any(list) simply means "at least one element of the list evaluates to
true". This is trivially false for the empty list - there are no
elements to be true.

These are logical functions and should be mathematically sound. It's
possible to add all sorts of problems if we just arbitrarily decide
what "for all x" should mean. We may just as well decide that for
convenience: math.pi == 3.


I agree.

Some amateur maths - applying the identities of a 'two-element Boolean
algebra' found here:

http://en.wikipedia.org/wiki/Two-ele...oolean_algebra

def any(S):
for x in S:
if x:
return True
return False

def all(S):
for x in S:
if not x:
return False
return True

#the identities don't hold if you use the alternative
##def all(S):
## ret_val = False
##
## for x in S:
## ret_val = True
## if not x:
## return False
##
## return ret_val

empty = []
universe = [ 0, 1 ]

one = all(empty)
zero = any(empty)

assert (one or one) == one
assert (one or zero) == one
assert (zero or one) == one
assert (zero or zero) == zero
assert (zero and zero) == zero
assert (zero and one) == zero
assert (one and zero) == zero
assert (one and one) == one
assert (not one) == zero
assert (not zero) == one

#on the other hand
one = all(universe)
zero = any(universe)

#de Morgan - swap 'and' and 'or' and complement the result
assert not(one and one) != one
assert not(one and zero) != one
assert not(zero and one) != one
assert not(zero and zero) != zero
assert not(zero or zero) != zero
assert not(zero or one) != zero
assert not(one or zero) != zero
assert not(one or one) != one
assert not(not one) != zero
assert not(not zero) != one

----------------------------------------------------------------------

Gerard

Mar 31 '06 #45

Ron Adam wrote:
Carl Banks wrote:
In Python, yes and no are the only possible answers. Probably the only
analogous thing you could do in Python would be for all() to raise
ValueError when passed an empty sequence.


There is also 'None' which serves a similar purpose of indicating an
invalid value when passing arguments.


If all() were to return None, then if would essentially be like
returning False, because an if-statement would treat False and None the
same (as would most anything else expecting a boolean value).

The only reasonable way to say "false assumption" in Python is to raise
an exception.
Carl Banks

Mar 31 '06 #46
Carl Banks wrote:
Ron Adam wrote:
Carl Banks wrote:
In Python, yes and no are the only possible answers. Probably the only
analogous thing you could do in Python would be for all() to raise
ValueError when passed an empty sequence.

There is also 'None' which serves a similar purpose of indicating an
invalid value when passing arguments.


If all() were to return None, then if would essentially be like
returning False, because an if-statement would treat False and None the
same (as would most anything else expecting a boolean value).

The only reasonable way to say "false assumption" in Python is to raise
an exception.
Carl Banks


Then maybe None should be evaluated as True so it is consistent with
all(). ;-)
Not serious of course, Cheers,
Ron



Mar 31 '06 #47
Ant
lol!

Mar 31 '06 #48
Ron Adam <rr*@ronadam.com> writes:
The 'not not S' is just a conversion to bool. Is the following less
contorted to you?
>>> bool([])
False


Oh ok. Yes, bool(S) is much less contorted than "not not S".
'Is all True' isn't the same as 'Has all True'. As I said, I'm not
questioning the mathematical meaning of the set relation 'is all
True', but wondering weather or not an alternate relation 'has all
True' would be better for use as a flow control test.

Do you have some examples uses since it's obvious to you?
# go out drinking when I'm finished with today's work
if all (task.done() for task in self.things_to_do_today()):
self.go_out_drinking()

If I didn't have anything to do today, that should result in going out
drinking immediately.
I just have a feeling we will see a lot of "S and all(S)" expressions
being used. Maybe that's not so bad, but I would prefer to not have
to do that if it turns out to the standard idiom for all testing
within a loop.


I think "S and all(S)" is the right way to express that, if that's
what's intended.
Apr 1 '06 #49
On Fri, 31 Mar 2006 16:29:00 -0800, Paul Rubin wrote:
I think "S and all(S)" is the right way to express that, if that's
what's intended.


I still would like a standard function, because "S and all(S)" does not
work with iterators. I proposed one possible function, truecount(S), that
returns a tuple of how many were true and how many there were total. Then
you could do

true_count, count = truecount(S)

if count and true_count == count:
# nonempty list and all are true
And S could be an iterator or generator function expression.

You can easily write your own truecount() but it would be nice to have
something like that as standard. I don't much like the name "truecount"
though; I'm open to suggestions for a better name.
--
Steve R. Hastings "Vita est"
st***@hastings.org http://www.blarg.net/~steveha

Apr 1 '06 #50

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

16 posts views Thread by Ajay | last post: by
1 post views Thread by Tzury Bar Yochay | last post: by
6 posts views Thread by =?Utf-8?B?SFJzb2Z0IEluZm9ybcOhdGljYQ==?= | last post: by
4 posts views Thread by Hill | last post: by
reply views Thread by Hans Kesting | last post: by
3 posts views Thread by geraldjr30 | last post: by
1 post views Thread by Waqarahmed | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.