I am trying to yield each row of CSV as list of int, float, str respectively while using list comprehension with if statements.
How do I write a list comprehension with if statements that will convert each element of CSV row into int, float, str respectively ?
Problem: float created as string.
import csv
FILE = "file.csv"
def all_values(file):
with open(file, "r") as file_open:
reader = csv.reader(file_open)
for row in reader:
yield [
int(x)
if x.isnumeric() else float(x)
if x.isdecimal() else x
for x in row
]
values = [x for x in all_values(FILE)]
print(values)
Problem in part of code:
yield [
int(x)
if x.isnumeric() else float(x)
if x.isdecimal() else x
for x in row
]
File:
100,"Jin",10.56
200,"Tonic",15.99
300,"Vodka",20.39
Output:
[[100, 'Jin', '10.56'], [200, 'Tonic', '15.99'], [300, 'Vodka', '20.39']]
Wrong type of values:
'10.56', '15.99', '20.39'
Thank you for your time.
CodePudding user response:
As mentioned in the comments isdecimal() is returning False because . is not considered a decimal character. Instead you could change your code to be:
yield [
int(x)
if x.isnumeric() else float(x)
if x.replace('.','',1).isdigit() else x
for x in row
]
In this case the order of the checks matter, int must be first.
CodePudding user response:
Another option to make it a bit safer if its a float or not:
def is_float(element) -> bool:
try:
float(element)
return True
except ValueError:
return False
def all_values(file):
with open(file, "r") as file_open:
reader = csv.reader(file_open)
for row in reader:
yield [
int(x)
if x.isnumeric() else float(x)
if is_float(x) else x
for x in row
]
