60

I have a string of data with the following format: xpos-ypos-zoom (i.e. 8743-12083-15) that I want to split up and store in the variables xpos, ypos, and zoom. Since I need to do some calculations with these number I'd like to convert them to integers right from the beginning. Currently, the way I'm doing this is with the following code:

file = '8743-12083-15'
xval, yval, zoom  = file.split("-")
xval = int(xval)
yval = int(yval)

It seems to me there should be a more efficient way of doing this. Any ideas?

4 Answers 4

110

My suggestion is a list comprehension.

test = '8743-12083-15'
lst_int = [int(x) for x in test.split("-")]

As to which is most efficient (cpu-cyclewise) is something that should always be tested.

Some quick testing on my Python 2.6 install indicates map is probably the most efficient candidate here (building a list of integers from a value-splitted string). Note that the difference is so small that this does not really matter until you are doing this millions of times (and it is a proven bottleneck)...

def v1():
    return [int(x) for x in '8743-12083-15'.split('-')]

def v2():
    return map(int, '8743-12083-15'.split('-'))

import timeit
print "v1", timeit.Timer('v1()', 'from __main__ import v1').timeit(500000)
print "v2", timeit.Timer('v2()', 'from __main__ import v2').timeit(500000)

Output:

v1 3.73336911201 
v2 3.44717001915
Sign up to request clarification or add additional context in comments.

1 Comment

map is usually faster than comprehension when using a builtin functions, and slower if you are using a user defined function (including lambda)
24

efficient as in fewer lines of code?

(xval,yval,zval) = [int(s) for s in file.split('-')]

2 Comments

I'd declare this answer to be efficient as in "easiest to code and move on to other more important stuff, and to understand when I come back to it later". Trying to eke out microseconds of performance from this particular line of code is clearly a detour into the Tarpit of Unnecessary Optimization.
I generally agree and that is exactly why I did not brush it up (although I am aware of the generator expressions and the like). But, since the matter in question is about three elements it might as well be left as is
19

This works in Python 2 and 3:

xval, yval, zval = map(int, file.split('-'))

Note: You might want to pick a different name for file as it shadows the builtin.

Comments

14

You can map the function int on each substring, or use a list comprehension:

>>> file = '8743-12083-15'
>>> list(map(int, file.split('-')))
[8743, 12083, 15]
>>> [int(d) for d in file.split('-')]
[8743, 12083, 15]

In the above the call to list is not required, unless working with Python 3.x. (In Python 2.x map returns a list, in Python 3.x it returns a generator.)

Directly assigning to the three variables is also possible (in this case a generator expression instead of a list comprehension will do):

>>> xval, yval, zval = (int(d) for d in file.split('-'))
>>> xval, yval, zval
(8743, 12083, 15)

1 Comment

Don't worry, if you are assigning the map() to a tuple it will still work in Python 3

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.