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