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?
$ 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]
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().)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With