The “ValueError: could not convert string to float:<>” is an exception that is raised when we attempt to convert a string that cannot be converted into float using the float() function, for example, an empty string and a string with non-numeric characters.
In this article, we will see how to reproduce the error and how to fix it.
Reproduce “ValueError: could not convert string to float:<>”
In most cases, the error is raised in cases like the following:
Case 1: Attempting to convert an empty string to float.
1 |
print(float("")) # Empty string |
Output:
ValueError: could not convert string to float: ''
Case 2: Trying to convert a string with non-numeric characters
1 |
print(float("b2.67")) # using non-numeric characters |
Output:
ValueError: could not convert string to float: 'b2.67'
1 |
print(float("2,134")) # comma is not accepted |
Output:
ValueError: could not convert string to float: '2,134'
There are, however, some exceptions to Case 2. Let’s look at some of them.
Exceptions to Case 2
Using non-numeric characters in a string does not always raise the “could not convert string to float:<>” error when the string is converted to float. Here are some examples of such cases.
Example 1: Using “_” within the numerical literal
Underscore, “_”, can be used to group digits to enhance readability. In this case, the underscore within the string to be converted may not raise an error. Examples,
1 2 3 4 5 6 |
print(float("21_34")) print(float("2_134_567")) print(float("-45.98_98")) # The following two lines will cause an error - wrong usage of "_" # print(float("+_45.8")) # print(float("-45._8")) |
Output:
2134.0 2134567.0 -45.9898
Example 2: Exponent floating point literals
When used correctly within a Python number, the letters “e” or “E” are interpreted as radix 10. For example,
1 2 3 4 5 6 7 |
print(float("1e3")) print(float("64E-2")) print(float("0e0")) print(float("-0.9e5")) # Wrong use of E/e. The following two lines yield errors. #print(float("e3")) #print(float("10e")) |
Output:
1000.0 0.64 0.0 -90000.0
You can read more about the exceptions here: https://docs.python.org/3/reference/lexical_analysis.html#numbers
Solution to “ValueError: could not convert string to float:<>”
This section discusses three methods of fixing the error.
Method 1: Use a try-except statement to catch the error
In this method, we try to convert the string to float, and if that leads to ValueError, we do something else. In the following example, we set the result to 0.0.
1 2 3 4 5 6 7 8 9 10 11 |
str1 = "b2.67" try: num1 = float(str1) except ValueError as e: # If the string cannot be converted to float # set num1 to 0.0 (you can use any other value as default) # and print the error num1 = 0.0 print(e) print(num1) |
Output:
could not convert string to float: 'b2.67' 0.0
Here is another example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
lst1 = ["34,5", "89.9", "657z", "+45", "65%", "-78", "89e5"] def string_to_float(value1): """ Input: value Returns float type of value1 if it can be converted to float else return the default value (0.0) """ try: num1 = float(value1) except ValueError: num1 = 0.0 return num1 # Apply the function string_to_float to each value in lst1 using map # then convert the map generator into a list using the list() function. result = list(map(string_to_float, lst1)) print(result) |
Output:
[0.0, 89.9, 0.0, 45.0, 0.0, -78.0, 8900000.0]
Method 2: Using re to remove unwanted characters in the string
This solution removes all unnecessary characters in the string using the re.sub() function by substituting non-numeric characters (\D) with an empty string (“”). Let’s see an example,
1 2 3 4 5 6 7 8 9 10 |
import re str1 = "234,678" # Replace any non-decimal ("\D+") with empty string ("") # effectively, removing non-numeric characters result = re.sub(r"\D+", "", str1) print(result) print(type(result)) # Then convert the result into a float print(float(result)) |
Output:
234678 <class 'str'> 234678.0
Another example
1 2 3 4 5 6 7 8 9 10 |
import re # defining a lambda function accepting x, remove unwanted characters from # it using re.sub(), and convert it into float. to_float = lambda x: float(re.sub(r"\D+", "", x)) lst1 = ["34,5", "89.9", "a657z", "r45b", "65$", "y78", "89fy10"] # Apply the to_float() function to every item in lst1. result = list(map(to_float, lst1)) print(result) |
Output:
[345.0, 899.0, 657.0, 45.0, 65.0, 78.0, 8910.0]
Note: This method will fail in the cases discussed under the “Exceptions to Case 2” section. The pattern “\D+” will not understand the exceptions discussed unless we use a more robust pattern. In fact, “\D+”, will remove “+” and “-” for the cases used to define positive and negative numbers. See below.
1 2 3 4 5 6 7 |
import re to_float = lambda x: float(re.sub(r"\D+", "", x)) lst1 = ["-34.5", "+89", "6.8e3", "45", "-6.7e-2", "-78", "-89e5"] result = list(map(to_float, lst1)) print(result) |
Output:
[345.0, 89.0, 683.0, 45.0, 672.0, 78.0, 895.0]
As shown in the output, the regex pattern “\D+” failed to do what we expected. It removes +/-, decimal (.), and even the lexical character “e”.
The easiest way to solve this problem is to use a try-except statement and re simultaneously. Let’s see that.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import re def string_to_float2(value1): """ Input: value Returns float type of value1 if it can be converted to float else return the default value (0.0) """ try: num1 = float(value1) except ValueError: # if the direct conversion failed, use regex to remove unwanted characters. num1 = float(re.sub(r"\D+", "", value1)) return num1 lst1 = ["34,5", "89.9", "657z", "+45", "65%", "-78", "89e5", "567b", "yt156"] result = list(map(string_to_float2, lst1)) print(result) |
Output:
[345.0, 89.9, 657.0, 45.0, 65.0, -78.0, 8900000.0, 567.0, 156.0]
Method 3: Using <str>.replace or <str>.strip
This solution mostly works when you know the nature of the strings you are trying to convert.
The <str>replace() method is used to replace unwanted characters anywhere in the string, whereas <str>.strip() removes the specific leading and trailing characters.
The latter assumes that the unwanted characters are contained on the string’s left or right side.
Here are some examples
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
str1 ="b678b" str1 = str1.strip("b") result = float(str1) print(result) str2 = "2719,9#" str2 = str2.replace(",", "").replace("#", "") result = float(str2) print(result) # in cases where a comma is used as a decimal delimiter str3 = "4,567" str3 = str3.replace(",", ".") result = float(str3) print(result) |
Output:
678.0 27199.0 4.567
Conclusion
This method discussed ways of reproducing and solving “ValueError: could not convert string to float:<>”. The try-except method should be sufficient in most cases, but if you need to parse numbers from a string containing non-numeric, use methods 2 and 3.