1

I wanna converts all strings in numeric columns 2-3 ("weight" and "age") to a number or None.

data = [('marvin', 'dog', 25, "1"),
        ('garfield', 'cat', "N/A", 8),
        ('rosie', 'cat', 14, None),
        ('fred', 'dog', 20, "7")]

I wanna use try/except type but got stuck.

This is my code:

output1 = []
for d in data:
    try:
        foo = (d[0], d[1], float(d[2]), float(d[3]))
        output1.append(foo)
    except:
        output1.append((d[0], d[1], None, None))
output1

Expected results should be:

[('marvin', 'dog', 25.0, 1.0),
('garfield', 'cat', None, 8.0),
('rosie', 'cat', 14.0, None),
 ('fred', 'dog', 20.0, 7.0)]

But I got:

[('marvin', 'dog', 25.0, 1.0),
 ('garfield', 'cat', None, None),
 ('rosie', 'cat', None, None),
 ('fred', 'dog', 20.0, 7.0)]
WyattN
  • 11
  • 3

3 Answers3

4

I would suggest you make a function to make the conversion to float:

def try_convert_to_float(x):
    try:
        return float(x)
    except ValueError:
        return None

output1 = []
for d in data:
    foo = (d[0], d[1], try_convert_to_float(d[2]), try_convert_to_float(d[3]))
    output1.append(foo)

print(output1)
#[('marvin', 'dog', 25.0, 1.0),
# ('garfield', 'cat', None, 8.0),
# ('rosie', 'cat', 14.0, None),
# ('fred', 'dog', 20.0, 7.0)]
pault
  • 41,343
  • 15
  • 107
  • 149
  • Thank u, I just tried to treat them independently. But your way looks more pretty. – WyattN Sep 26 '19 at 15:07
  • 1
    @WyattN another thing to note is that it's bad practice to have a "naked" except: [Should I always specify an exception type in `except` statements?](https://stackoverflow.com/questions/14797375/should-i-always-specify-an-exception-type-in-except-statements). (I had this problem in my original post, but have updated.) – pault Sep 26 '19 at 15:29
0

You should use the try / except for each value once at a time. It should look like this:

output1 = []
for row in data:
    output_row = [row[0], row[1]]
    for c in [row[2], row[3]]:
        try:
            foo = float(c)
            output_row.append(foo)
        except:
            output_row.append(None)
    output1.append(tuple(output_row))
Silveris
  • 1,048
  • 13
  • 31
0

The problem is that you always enter the except loop because None and "N/A" can't be converted to float. You have to use try/except for each value separately as shown above.

def get_float(el):
    try:
        return float(el)
    except (TypeError, ValueError) as e:
        return None

output = []
for d in data:
    output.append((d[0], d[1], get_float(d[2]), get_float(d[3])))

However, you have to catch both TypeError (for the None value) and ValueError (for the "N/A" string).

output:

[('marvin', 'dog', 25.0, 1.0),
('garfield', 'cat', None, 8.0),
('rosie', 'cat', 14.0, None),
('fred', 'dog', 20.0, 7.0)]
Julia K
  • 397
  • 3
  • 10