55

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?

Ian Burris
  • 6,325
  • 21
  • 59
  • 80

4 Answers4

101

My original suggestion with a list comprehension.

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

EDIT:

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 
> output v2 3.44717001915
ChristopheD
  • 112,638
  • 29
  • 165
  • 179
  • 4
    map is usually faster than comprehension when using a builtin functions, and slower if you are using a user defined function (including lambda) – John La Rooy Oct 15 '09 at 20:30
20

efficient as in fewer lines of code?

(xval,yval,zval) = [int(s) for s in file.split('-')]
Bartosz Radaczyński
  • 18,396
  • 14
  • 54
  • 61
  • 3
    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. – PaulMcG Oct 15 '09 at 21:56
  • 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 – Bartosz Radaczyński Oct 16 '09 at 20:09
16

note: you might want to pick a different name for file as it shadows the buildtin

this works in Python 2 and 3


xval,yval,zval = map(int,file.split('-'))
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
13

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)
Stephan202
  • 59,965
  • 13
  • 127
  • 133