Why Python 3?

MRAB python at mrabarnett.plus.com
Sun Apr 20 12:41:09 EDT 2014


On 2014-04-20 17:22, Ian Kelly wrote:
>
> On Apr 19, 2014 2:54 PM, "Chris Angelico" <rosuav at gmail.com
> <mailto:rosuav at gmail.com>> wrote:
>  >
>  > On Sun, Apr 20, 2014 at 6:38 AM, Ian Kelly <ian.g.kelly at gmail.com
> <mailto:ian.g.kelly at gmail.com>> wrote:
>  > >> Or you just cast one of them to float. That way you're sure you're
>  > >> working with floats.
>  > >
>  > > Which is inappropriate if the type passed in was a Decimal or a
> complex.
>  >
>  > In that case, you already have a special case in your code, so whether
>  > that special case is handled by the language or by your code makes
>  > little difference. Is your function so generic that it has to be able
>  > to handle float, Decimal, or complex, and not care about the
>  > difference, and yet has to ensure that int divided by int doesn't
>  > yield int? Then say so; put in that special check. Personally, I've
>  > yet to meet any non-toy example of a function that needs that exact
>  > handling; most code doesn't ever think about complex numbers, and a
>  > lot of things look for one specific type:
>
> When I'm writing a generic average function, I probably don't know
> whether it will ever be used to average complex numbers. That shouldn't
> matter, because I should be able to rely on this code working for
> whatever numeric type I pass in:
>
> def average(values):
>      return sum(values) / len(values)
>
> This works for decimals, it works for fractions, it works for complex
> numbers, it works for numpy types, and in Python 3 it works for ints.
>
>  > Maybe it's not your code that should be caring about what happens when
>  > you divide two integers, but the calling code. If you're asking for
>  > the average of a list of numbers, and they're all integers, and the
>  > avg() function truncates to integer, then the solution is to use sum()
>  > and explicitly cast to floating point before dividing.
>
> First, that's not equivalent.  Try the following in Python 3:
>
> values = [int(sys.float_info.max / 10)] * 20
> print(average(values))
>
> Now try this:
>
> print(average(map(float, values)))
>
> I don't have an interpreter handy to test, but I expect the former to
> produce the correct result and the latter to raise OverflowError on the
> call to sum.
>

Python 3.4.0 (v3.4.0:04f714765c13, Mar 16 2014, 19:25:23) [MSC v.1600 64 
bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
 >>> import sys
 >>> def average(values):
...     return sum(values) / len(values)
...
 >>> values = [int(sys.float_info.max / 10)] * 20
 >>> print(average(values))
1.7976931348623158e+307
 >>> print(average(map(float, values)))
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "<stdin>", line 2, in average
TypeError: object of type 'map' has no len()
 >>> print(average(list(map(float, values))))
inf
 >>>

In fact, that's true back to Python 3.1

> Second, why should the calling code have to worry about this
> implementation detail anyway? The point of a generic function is that
> it's generic.
>




More information about the Python-list mailing list