1

I want to convert a list of string representations of tuples, such as:

["(279, 256000, '.m4a')", "(217, 256000, '.m4a')", "(174, 128000, '.mp3')"]

into a list of tuples, such as:

[(279, 256000, '.m4a'), (217, 256000, '.m4a'), (174, 128000, '.mp3')]

This seems to be the most concise (and clear) way to do it

recs = ... # loaded from text file
data  = map(eval, recs)  

However, Ive seen a posting Python course - lambda that seems to imply map() may not be good python or may become deprecated.

The alternative would seem to be something like the more verbose (and hence slightly less clear):

data = []
for r in recs:
    data += [eval(r)]

Which is more pythonic?

2 Answers 2

8

map is fine when used with a named function; it’s when you use it with an inline lambda that a list comprehension or generator expression becomes cleaner. eval, on the other hand, is not really fine. Consider ast.literal_eval instead.

import ast

data = map(ast.literal_eval, recs)

Also, map returns an iterable (in Python 3); if you want a list, you’ll have to call list on the result.

data = list(map(ast.literal_eval, recs))
Sign up to request clarification or add additional context in comments.

3 Comments

Pardon my ignorance (fairly new to Python) , but why is eval 'not really fine'? As proof of my newness, I havent yet come across ast - will check that out, thanks for the tip. ... I suspected the loop was not 'pythonic', thanks for the alternative.
@RFlack: eval can execute arbitrary code, so it’s not safe to use on user input. Even if you think that doesn’t apply to your case, related security vulnerabilities have a habit of sneaking in, so it’s best to use a more restrictive equivalent if possible.
ah that makes sense. in this case the data are 'safe' being written by (my) program, not user input. But I take your point. Thanks.
3

In my opinion using map is a nice functional solution, but can be seen as a redundant language feature since generators were added. On the other hand your example that iterates over the array and concatenates to a list is not Pythonic.

Some Pythonic alternatives to map:

# a list comprehesion
[ast.literal_eval(r) for r in recs]

or

# a generator expression
(ast.literal_eval(r) for r in recs)

or

# a generator function
def mapYourData(recs):
  for r in recs:
    yield ast.literal_eval(r)

Don't forget to import ast

EDIT: as @minitech pointed out you shold use ast.literal_eval instead of eval.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.