0
my_list=[['A','B','C','0.0'],['D','E','F','1.2'],['G','H','I','0'],['J','K','L','M']]

I tried these but they can only convert whole numbers into floats and leaves the rest as strings.

[[float(x) if x.isnumeric() else x for x in i] for i in my_list]
for i, sublist in enumerate(my_list):
     for j, x in enumerate(sublist):
            if x.isnumeric():
                my_list[i][j] = float(x)

Expected output

[['A','B','C',0.0],['D','E','F',1.2],['G','H','I',0],['J','K','L','M']]
catzen
  • 75
  • 8
  • 2
    As a rule, you never want to use text tests for stuff like this. If the goal is "something parsable as an X", then the solution is "parse it as an X and catch the exception if it fails". The parsers for `float` and `int` handle *many* more cases than simple string methods can verify. As you've discovered, a period is not considered a numeric character, nor is a minus sign (for negative numbers), the letter `e` (e.g. for the valid float `1.2e10`), etc. The `float`/`int` constructors have no trouble with leading or trailing whitespace too, but your string tests won't see them as numeric either. – ShadowRanger Aug 19 '20 at 12:57

3 Answers3

2

If you have no other criterion than "anything might or mightn't be a valid float", then just try them all:

def try_float(value):
    try:
        return float(value)
    except ValueError:
        return value

result = [[try_float(v) for v in l] for l in my_list]
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
deceze
  • 510,633
  • 85
  • 743
  • 889
0

.isnumeric does not return True for float numbers represented as strings. It returns true for strings that only consists of numbers, . is not a number.

This is why your solution only converts integers, not floats.

The best choice to check if a string is a float, and hence convert it - is to just try float() and catching the raised ValueError and simply continuing.

If you know the nesting is only one level deep, deceze's solution should do it great.

If there may be more nesting, you could try a recursive function-

def convert_float(l: list):
    for i, v in enumerate(l):
        if type(v) == list:
            convert_float(v)
            continue
        try:
            l[i] = float(v)
        except ValueError:
            continue
alani
  • 12,573
  • 2
  • 13
  • 23
Chase
  • 5,315
  • 2
  • 15
  • 41
0

You can also use regex to find this. Something like below:

In [105]: import re

In [106]: r = re.compile(r"^\d*[.,]?\d*$")

In [107]: [[float(v) if r.match(v) else v for v in l] for l in my_list]
Out[107]: 
[['A', 'B', 'C', 0.0],
 ['D', 'E', 'F', 1.2],
 ['G', 'H', 'I', 0.0],
 ['J', 'K', 'L', 'M']]
Mayank Porwal
  • 33,470
  • 8
  • 37
  • 58