Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: How can I read in the characters from a line in a file and convert them to floats and strs, depending on if they are numbers or letters?

Tags:

python

input

I have a file that looks like:

1 1 C C 1.9873 2.347 3.88776

1 2 C Si 4.887 9.009 1.21

I would like to read in the contents of the file, line-by-line. When I only had numbers on the lines I used:

for line in readlines(file):
    data = map(float, line.split)

But this only works when all the elements of line.split are numbers. How can I make it store the letters as strings and the numbers as floats?

like image 202
mshaughnessy Avatar asked Jan 17 '23 08:01

mshaughnessy


2 Answers

$ cat 1.py
def float_or_str(x):
  try:
     return float(x)
  except ValueError:
     return x

line = '1 1 C C 1.9873 2.347 3.88776'
print map(float_or_str, line.split())

$python 1.py
[1.0, 1.0, 'C', 'C', 1.9873, 2.347, 3.88776]
like image 78
Igor Chubin Avatar answered Jan 18 '23 23:01

Igor Chubin


for line in infile:
    data = [x if x.isalpha() else float(x) for x in line.split()]

There will be issues if your data contains fields that are neither alphabetic nor valid floating-point numbers (for example, "A1"). Your data doesn't seem to have these from what you said, but if it does, the try/except approach suggested by Igor would probably suit better.

I would probably use a more generic function that can be given the types to try, however:

def tryconvert(value, *types):
    for t in types:
        try:
            return t(value)
        except (ValueError, TypeError):
            continue
    return value

for line in infile:
    data = [tryconvert(x, int, float) for x in line.split()]

This will convert anything that be converted to an integer to an int, failing that it will try float, and then finally it just gives up and returns the original value, which we know will be a string. (If we didn't know it was a string we could just stick str on the end of our call to tryconvert().)

like image 27
kindall Avatar answered Jan 18 '23 22:01

kindall