I am working on an exercise that states:
Let
s
be a string that contains a sequence of decimal numbers separated by commas, e.g.,s = '1.23,2.4,3.123'
. Write a program that prints the sum of the numbers ins
.
My solution is:
s = '1.23,2.4,3.123'
news = s + ","
value = ""
floatValue = 0
for i in range(len(news)):
if news[i] != ',':
value += s[i]
elif news[i] == ',':
floatValue += float(value)
value = ""
print floatValue
I was just wondering if there is a more efficient way to do this? Also I'm in the beginning of a Python course so at this point I am only trying to accomplish this with a beginner-level solution.
Yes, significantly:
>>> s = '1.23,2.4,3.123'
>>> sum(map(float, s.split(",")))
6.753
This uses str.split
to divide the string up into numbers:
>>> s.split(",")
['1.23', '2.4', '3.123']
map
to apply float
to each string
>>> map(float, s.split(","))
[1.23, 2.4, 3.123]
and sum
to add up the total.
As there are several answers with slightly different approaches, I thought I'd test them out to see which was most efficient:
2.7.6
>>> import timeit
>>> def f1(s):
return sum(map(float, s.split(",")))
>>> def f2(s):
return sum(float(x) for x in s.split(","))
>>> def f3(s):
return sum([float(x) for x in s.split(",")])
>>> timeit.timeit("f1(s)", setup="from __main__ import f1, f2, f3;s='1.23,2.4,3.123'")
2.627161979675293
>>> timeit.timeit("f2(s)", setup="from __main__ import f1, f2, f3;s='1.23,2.4,3.123'")
2.805773973464966
>>> timeit.timeit("f3(s)", setup="from __main__ import f1, f2, f3;s='1.23,2.4,3.123'")
2.6547701358795166
3.4.0
>>> timeit.timeit("f1(s)", setup="from __main__ import f1, f2, f3;s='1.23,2.4,3.123'")
2.3012791969995305
>>> timeit.timeit("f2(s)", setup="from __main__ import f1, f2, f3;s='1.23,2.4,3.123'")
3.1761953750028624
>>> timeit.timeit("f3(s)", setup="from __main__ import f1, f2, f3;s='1.23,2.4,3.123'")
3.1163038839986257
Bonus round for Ashwini (3.4.0):
>>> from ast import literal_eval
>>> def f4(s):
return sum(literal_eval(s))
>>> timeit.timeit("f4(s)", setup="from __main__ import f1, f2, f3, f4;s='1.23,2.4,3.123'")
23.054055102998973
>>> timeit.timeit("f1(s)", setup="from __main__ import f1, f2, f3, f4;s='1.23,2.4,3.123'")
2.2302689969983476
This works (slowly!) using ast.literal_eval
to interpret the string as a tuple of floats:
>>> literal_eval('1.23,2.4,3.123')
(1.23, 2.4, 3.123)