Hans Roelofsen
Hans Roelofsen

Reputation: 741

Convert list items to defined data type

I'm rather new to python and I'm not sure how to do the following.

I have a list foo containing metadata and measurement values for a certain plot. For example, a plotID, survey date, initials of surveyors, several measurement values and a categorical variable.

foo= ['plot001', '01-01-2013', 'XX', '10', '12.5', '0.65', 'A']

Because these data are read from a .txt, all list items are strings. My question is: how do I convert each list item to the approporiate datatype?. I can make a list with the desired data types:

dType= ['str', 'str', 'str', 'int', 'float', 'float', 'float', 'str']

It would be nice if I could apply each item in dType as function to the matching element in foo as such:

out= [str(foo[0]), str(foo[1]), str(foo[2]), int(foo[3]), float(foo[4]), float(foo[5]), float(foo[6]), str(foo[7])]

but I'm sure there must be a better solution! Thanks for any suggestions!

Upvotes: 2

Views: 5760

Answers (3)

roippi
roippi

Reputation: 25954

Instead of a list of strings, make dType a list of builtin factories:

dType= [str, str, str, int, float, float, str]

(you had an extra float that I removed)

Then just use zip:

[t(x) for t,x in zip(dType,foo)]
Out[6]: ['plot001', '01-01-2013', 'XX', 10, 12.5, 0.65, 'A']

Bonus: you could even get fancy and make your own factory functions and apply them in the same manner with functools.partial. Say, if you wanted that date to turn into a datetime object:

def datetime_factory(format,s):
    from datetime import datetime
    return datetime.strptime(s,format)

from functools import partial

dType= [str, partial(datetime_factory,'%d-%m-%Y'), str, int, float, float, str]

[t(x) for t,x in zip(dType,foo)]
Out[29]: ['plot001', datetime.datetime(2013, 1, 1, 0, 0), 'XX', 10, 12.5, 0.65, 'A']

(making our own factory def was needed here since partial only allows you to partially apply the leftmost arguments, and strptime requires the string-to-be-formatted first)

Upvotes: 7

mgilson
mgilson

Reputation: 309891

ast.literal_eval could be helpful:

>>> import ast
>>> def evaluate(x):
...     try:
...         return ast.literal_eval(x)
...     except (ValueError,SyntaxError):
...         return x
... 
>>> map(evaluate, foo)
['plot001', '01-01-2013', 'XX', 10, 12.5, 0.65, 'A']

Upvotes: 1

John1024
John1024

Reputation: 113834

foo= ['plot001', '01-01-2013', 'XX', '10', '12.5', '0.65', 'A']
fnlist= [str, str, str, int, float, float, str]
out = [fn(v) for fn, v in zip(fnlist, foo)]

Upvotes: 2

Related Questions