2

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!

2
  • Yes, the suggestion of @roippi works very fine. Thanks a lot! Commented Dec 14, 2013 at 19:40
  • And @John1024 also suggested this, thanks! Commented Dec 14, 2013 at 19:41

3 Answers 3

7

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)

Sign up to request clarification or add additional context in comments.

Comments

2
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)] 

Comments

1

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'] 

4 Comments

this doesn't work for the dates. I got ValueError: malformed string
Hi, thanks for your suggestions. Unfortunataly, it doesn't seem to work for me. The error reads: ValueError: malformed string
yeah, you're right. Hold on ... (that's what I get for answering and watching TV at the same time)
Yes, thanks, it works now! This is very nice because it elliminates the need for the dTypes list, so I can run this on any list containing any datatype. I'm not quite sure what the ast.literal_eval function exactly does though, would you care to elaborate on that?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.