4

I created this generator function:

def myRange(start,stop,step):
    r = start
    while r < stop:
        yield r
        r += step

and I use it in two different ways. 1st:

for x in myRange(0,1,0.1):
    print x

Result:

0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0

2nd way to call the function:

a = [x for x in myRange(0,1,0.1)]

which results in:

[0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999]

Why are the values generated different?

Alvin
  • 383
  • 5
  • 16

1 Answers1

8

It is not the order in which you called your generator, but the way you are presenting the numbers that caused this change in output.

You are printing a list object the second time, and that's a container. Container contents are printed using repr(), while before you used print on the float directly, which uses str()

repr() and str() output of floating point numbers simply differs:

>>> lst = [0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999]
>>> print lst
[0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999]
>>> for elem in lst:
...     print elem
... 
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
>>> str(lst[3])
'0.3'
>>> repr(lst[3])
'0.30000000000000004'

repr() on a float produces a result that'll let you reproduce the same value accurately. str() rounds the floating point number for presentation.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    Wondering, though... Does this mean `repr()` is subject to the same floating point representation inaccuracy as detailed [here](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)? – WGS Oct 21 '14 at 17:03
  • 1
    @Nanashi: of course it is. All that `repr()` does is reveal the actual float value, not round it to a human readable version. – Martijn Pieters Oct 21 '14 at 17:04
  • 1
    Wow, I didn't know that's how `repr()` works at all. This shed more light than an awful lot of other `repr() vs str()` tutorials I've read. Thanks! – WGS Oct 21 '14 at 17:06
  • @NullDev note that around Python 3.2, things changed so that for floating point numbers there's no difference between `str` and `repr`. I've edited the relevant link into the duplicates list. – Mark Ransom Dec 18 '21 at 19:46