473,728 Members | 1,454 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

max(), sum(), next()

Empty Python lists [] don't know the type of the items it will
contain, so this sounds strange:
>>sum([])
0

Because that [] may be an empty sequence of someobject:
>>sum(s for s in ["a", "b"] if len(s) 2)
0

In a statically typed language in that situation you may answer the
initializer value of the type of the items of the list, as I do in the
sum() in D.

This sounds like a more correct/clean thing to do:
>>max([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: max() arg is an empty sequence

So it may be better to make the sum([]) too raise a ValueError, in
Python 3/3.1 (if this isn't already true). On the other hand often
enough I have code like this:
>>max(fun(x) for x in iterable if predicate(x))
This may raise the ValueError both if iterable is empty of if the
predicate on its items is always false, so instead of catching
exceptions, that I try to avoid, I usually end with a normal loop,
that's readable and fast:

max_value = smallvalue
for x in iterable:
if predicate(x):
max_value = max(max_value, fun(x))

Where running speed matters, I may even replace that max(max_value,
fun(x)) with a more normal if/else.

A possible alternative is to add a default to max(), like the next()
built-in of Python 2.6:
>>max((fun(x) for x in iterable if predicate(x)), default=smallva lue)
This returns smallvalue if there are no items to compute the max of.

Bye,
bearophile
Sep 3 '08 #1
54 8348
<be************ @lycos.comwrote :
>Empty Python lists [] don't know the type of the items it will
contain, so this sounds strange:
>>>sum([])
0
>>help(sum)
sum(...)
sum(sequence, start=0) -value
>>sum(range(x ) for x in range(5))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'list'
>>sum((range( x) for x in range(5)), [])
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]

.... so the list might not know what type it contains, but sum
does. And if you don't tell it, it makes a sensible guess. And
it *is* a case where refusing the temptation to guess is the
wrong thing: how many times would you use sum to do anything
other than sum numeric values? And how tedious would it be to
have to write sum(..., 0) for every other case? Particularly
bearing in mind:
>>sum(["a", "b"], "")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sum() can't sum strings [use ''.join(seq) instead]

--
\S -- si***@chiark.gr eenend.org.uk -- http://www.chaos.org.uk/~sion/
"Frankly I have no feelings towards penguins one way or the other"
-- Arthur C. Clarke
her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump
Sep 3 '08 #2
be************@ lycos.com wrote:
Empty Python lists [] don't know the type of the items it will
contain, so this sounds strange:

>>>sum([])
0

Because that [] may be an empty sequence of someobject:
You are right in that sum could be used to sum arbitrary objects.
However, in 99.99% of the cases, you will be summing numerical values.
When adding real numbers, the neutral element is zero. ( X + 0 = X) It
is very logical to return zero for empty sequences.

Same way, if we would have a prod() function, it should return one for
empty sequences because X*1 = X. The neutral element for this operation
is one.

Of course this is not good for summing other types of objects. But how
clumsy would it be to use

sum( L +[0] )

or

if L:
value = sum(L)
else:
value = 0

instead of sum(L).

Once again, this is what sum() is used for in most cases, so this
behavior is the "expected" one.

Another argument to convince you: the sum() function in SQL for empty
row sets returns zero in most relational databases.

But of course it could have been implemented in a different way... I
believe that there have been excessive discussions about this decision,
and the current implementation is very good, if not the best.

Best,

Laszlo

Sep 3 '08 #3
On Sep 3, 8:18*pm, Laszlo Nagy <gand...@shopze us.comwrote:
bearophileH...@ lycos.com wrote:
Empty Python lists [] don't know the type of the items it will
contain, so this sounds strange:
>>sum([])
0
Because that [] may be an empty sequence of someobject:

You are right in that sum could be used to sum arbitrary objects.
However, in 99.99% of the cases, you will be summing numerical values.
When adding real numbers, the neutral element is zero. ( X + 0 = X) It
is very logical to return zero for empty sequences.

Same way, if we would have a prod() function, it should return one for
empty sequences because X*1 = X. The neutral element for this operation
is one.

Of course this is not good for summing other types of objects. But how
clumsy would it be to use

sum( L +[0] )

or

if L:
value = sum(L)
else:
value = 0

instead of sum(L).

Once again, this is what sum() is used for in most cases, so this
behavior is the "expected" one.

Another argument to convince you: the sum() function in SQL for empty
row sets returns zero in most relational databases.

But of course it could have been implemented in a different way... I
believe that there have been excessive discussions about this decision,
and the current implementation is very good, if not the best.
An alternative would be for the start value to default to None, which
would mean no start value. At the moment it starts with the start
value and then 'adds' the items in the sequence to it, but it could
start with the first item and then 'add' the following items to it.
So:

sum([1, 2, 3]) =6
sum(["a", "b", "c"]) ="abc"

For backward compatibility, if the sequence is empty and the start
value is None then return 0.
Sep 3 '08 #4
Laszlo Nagy:
I believe that there have been excessive discussions about this
decision, and the current implementation is very good, if not the best.
I see. But note that my post is mostly about the max()/min()
functions :-)

Bye,
bearophile
Sep 3 '08 #5
On Sep 3, 2:18*pm, Laszlo Nagy <gand...@shopze us.comwrote:
bearophileH...@ lycos.com wrote:
Empty Python lists [] don't know the type of the items it will
contain, so this sounds strange:
>>sum([])
0
Because that [] may be an empty sequence of someobject:

You are right in that sum could be used to sum arbitrary objects.
However, in 99.99% of the cases, you will be summing numerical values.
When adding real numbers, the neutral element is zero. ( X + 0 = X) It
is very logical to return zero for empty sequences.
No it isn't. Nothing is not 0, check with MS-Access, for instance:

Null + 1 returns Null. Any arithmetic expression involving a
Null evaluates to Null. Adding something to an unknown returns
an unknown, as it should.

It is a logical fallacy to equate unknown with 0.

For example, the water table elevation in ft above Mean Sea Level
is WTE = TopOfCasing - DepthToWater.

TopOfCasing is usually known and constant (until resurveyed).
But DepthToWater may or may not exist for a given event (well
may be covered with fire ants, for example).

Now, if you equate Null with 0, then the WTE calculation says
the water table elevation is flush with the top of the well,
falsely implying that the site is underwater.

And, since this particular site is on the Mississippi River,
it sometimes IS underwater, but this is NEVER determined by
water table elevations, which, due to the CORRECT treatment
of Nulls by Access, never returns FALSE calculations.
>>sum([])
0

is a bug, just as it's a bug in Excel to evaluate blank cells
as 0. It should return None or throw an exception like sum([None,1])
does.
>
Same way, if we would have a prod() function, it should return one for
empty sequences because X*1 = X. The neutral element for this operation
is one.

Of course this is not good for summing other types of objects. But how
clumsy would it be to use

sum( L +[0] )

or

if L:
value = sum(L)
else:
value = 0

instead of sum(L).

Once again, this is what sum() is used for in most cases, so this
behavior is the "expected" one.

Another argument to convince you: the sum() function in SQL for empty
row sets returns zero in most relational databases.

But of course it could have been implemented in a different way... I
believe that there have been excessive discussions about this decision,
and the current implementation is very good, if not the best.

Best,

Laszlo
Sep 3 '08 #6
On Sep 3, 7:48*am, bearophileH...@ lycos.com wrote:
Empty Python lists [] don't know the type of the items it will
contain, so this sounds strange:
>sum([])

0

Because that [] may be an empty sequence of someobject:
>sum(s for s in ["a", "b"] if len(s) 2)

0

In a statically typed language in that situation you may answer the
initializer value of the type of the items of the list, as I do in the
sum() in D.

This sounds like a more correct/clean thing to do:
>max([])

Traceback (most recent call last):
* File "<stdin>", line 1, in <module>
ValueError: max() arg is an empty sequence

So it may be better to make the sum([]) too raise a ValueError, in
Python 3/3.1 (if this isn't already true). On the other hand often
enough I have code like this:
>max(fun(x) for x in iterable if predicate(x))

This may raise the ValueError both if iterable is empty of if the
predicate on its items is always false, so instead of catching
exceptions, that I try to avoid, I usually end with a normal loop,
that's readable and fast:

max_value = smallvalue
for x in iterable:
* * if predicate(x):
* * * * max_value = max(max_value, fun(x))

Where running speed matters, I may even replace that max(max_value,
fun(x)) with a more normal if/else.

A possible alternative is to add a default to max(), like the next()
built-in of Python 2.6:
>max((fun(x) for x in iterable if predicate(x)), default=smallva lue)

This returns smallvalue if there are no items to compute the max of.

Bye,
bearophile
Two thoughts:
1/ 'Reduce' has a 'default' argument-- they call it 'initial'.
>>reduce( max, [ 0, 1, 2, 3 ] )
3
>>reduce( max, [ 0, 1, 2, 'a' ] )
'a'
>>reduce( max, [ 0, 1, 2, 'a', 'b' ] )
'b'

2/ Introduce a 'max' class object that takes a default type or default
argument. Query the default for an 'additive' identity, or query for
a 'comparitive' identity, comparisons to which always return true; or
call the constructor with no arguments to construct one.
Sep 3 '08 #7
On Wed, 03 Sep 2008 16:20:39 -0700, Mensanator wrote:
>>>sum([])
0

is a bug, just as it's a bug in Excel to evaluate blank cells as 0. It
should return None or throw an exception like sum([None,1]) does.
You're wrong, because 99.9% of the time when users leave a blank cell in
Excel, they want it to be treated as zero. Spreadsheet sum() is not the
same as mathematician's sum, which doesn't have a concept of "blank
cells". (But if it did, it would treat them as zero, since that's the
only useful thing and mathematicians are just as much pragmatists as
spreadsheet users.) The Excel code does the right thing, and your "pure"
solution would do the unwanted and unexpected thing and is therefore
buggy.

Bugs are defined by "does the code do what the user wants it to do?", not
"is it mathematically pure?". The current behaviour of sum([]) does the
right thing for the 99% of the time when users expect an integer. And the
rest of the time, they have to specify a starting value for the sum
anyway, and so sum([], initial_value) does the right thing *always*.

The only time it does the wrong thing[1] is when you forget to pass an
initial value but expect a non-numeric result. And that's the
programmer's error, not a function bug.

[1] I believe it also does the wrong thing by refusing to sum strings,
but that's another story.
--
Steven
Sep 4 '08 #8

Quoting Laszlo Nagy <ga*****@shopze us.com>:
be************@ lycos.com wrote:
Empty Python lists [] don't know the type of the items it will
contain, so this sounds strange:

>>sum([])
0

Because that [] may be an empty sequence of someobject:
You are right in that sum could be used to sum arbitrary objects.
However, in 99.99% of the cases, you will be summing numerical values.
When adding real numbers, the neutral element is zero. ( X + 0 = X) It
is very logical to return zero for empty sequences.
Even better:

help(sum) shows

===
sum(...)
sum(sequence, start=0) -value

Returns the sum of a sequence of numbers (NOT strings) plus the value
of parameter 'start'. When the sequence is empty, returns start.
===

so the fact that sum([]) returns zero is just because the start value is zero...
sum([],object()) would return an object().

BTW, the original code:
>>sum(s for s in ["a", "b"] if len(s) 2)
wouldn't work anyway... it seems that sum doesn't like to sum strings:
>>sum(['a','b'],'')
<type 'exceptions.Typ eError'>: sum() can't sum strings [use ''.join(seq) instead]

Cheers,

--
Luis Zarrabeitia
Facultad de Matemática y Computación, UH
http://profesores.matcom.uh.cu/~kyrie
Sep 4 '08 #9
Mensanator wrote:
No it isn't. Nothing is not 0, check with MS-Access, for instance:

Null + 1 returns Null. Any arithmetic expression involving a
Null evaluates to Null. Adding something to an unknown returns
an unknown, as it should.

It is a logical fallacy to equate unknown with 0.
http://en.wikipedia.org/wiki/Empty_sum

"In mathematics, the empty sum, or nullary sum, is the result of adding
no numbers, in summation for example. Its numerical value is zero."

</F>

Sep 4 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
10926
by: Stefan Bauer | last post by:
Hi NG, I have problem... I'm currently using UDB v8.1 for Linux. Here is the table "test": ID1 ID2 ID3 VALUE ----------------- 1 0 1 23 1 0 2 9
7
3240
by: turtle | last post by:
I want to find out the max value of a field on a report if the field is not hidden. I have formatting on the report and if the field doesn't meet a certain criteria then it is hidden. I want to get a max of the field for the ones that are not hidden. is this possible? TIA, KO
0
8896
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9416
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9269
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9192
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
6012
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4523
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4787
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3231
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2159
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.