map float string '0.0' puzzle

David M. Cooke cookedm+news at physics.mcmaster.ca
Wed Jan 28 00:44:20 CET 2004


At some point, "j vickroy" <jim.vickroy at noaa.gov> wrote:

> Howdy,
>
> I do not understand the following behavior for:
> PythonWin 2.3.2 (#49, Oct  2 2003, 20:02:00) [MSC v.1200 32 bit (Intel)] on
> win32.
>
>>>>
>>>> float('0.0')
> 0.0
>>>> row = ('0.0', '1.0', None)
>>>> map(lambda setting: setting and float(setting) or None, row)
> [None, 1.0, None]
>>>> map(lambda setting: setting and (setting,float(setting)) or
> (setting,None), row)
> [('0.0', 0.0), ('1.0', 1.0), (None, None)]
>>>>
>
> Specifically, why is the return value of the first map operation:
> [None, 1.0, None]
>
> I was expecting:
> [0.0, 1.0, None]

Because float('0.0') is a false value -- 0.0 is taken as false. So 
the lambda becomes
'0.0' and 0.0 or None
which evaluates to None.

It looks like you're trying to use the 'conditional expression' trick,
which fails in these situations. It'd be clearer to be more
expressive, and define a function:

>>> def float_to_str(s):
...     if s:
...         return float(s)
...     else:
...         return None
...
>>> [ float_to_str(s) for s in row ]
[0.0, 1.0, None]

where I've used a list comprehension instead of map. In fact, I'd
probably define float_to_str like this:
def float_to_str(s):
    try:
        return float(s)
    except:
        return None

which now works for anything: if it's convertible to float, it returns
the float, otherwise None.

-- 
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)physics(dot)mcmaster(dot)ca



More information about the Python-list mailing list