我的教授希望我创建一个函数,该函数返回字符串中的数字总和,但不使用任何列表或列表方法。
操作时该功能应如下所示:
>>> sum_numbers('34 3 542 11')
590
使用list和list方法时,通常很容易创建这样的函数。但试图在不使用它们的情况下这样做是一场噩梦。
我尝试了以下代码,但他们不能工作:
>>> def sum_numbers(s):
for i in range(len(s)):
int(i)
total = s[i] + s[i]
return total
>>> sum_numbers('1 2 3')
'11'
我没有将1,2和3全部转换为整数并加在一起,而是将字符串' 11'换句话说,字符串中的数字仍然没有转换为整数。
我也尝试使用map()
函数,但我得到了相同的结果:
>>> def sum_numbers(s):
for i in range(len(s)):
map(int, s[i])
total = s[i] + s[i]
return total
>>> sum_numbers('1 2 3')
'11'
答案 0 :(得分:6)
当然完全愚蠢,但为了好玩:
s = '34 3 542 11'
n = ""; total = 0
for c in s:
if c == " ":
total = total + int(n)
n = ""
else:
n = n + c
# add the last number
total = total + int(n)
print(total)
> 590
这假设所有字符(除了空格)都是数字。
答案 1 :(得分:2)
你肯定在这里付出了一些努力,但是你的方法的一部分肯定不会按原样运作:你在字符串中迭代字符,但你继续尝试将每个角色视为自己的号码。我编写了一个(非常评论的)方法,可以在不使用任何列表或列表方法的情况下完成您想要的任务:
def sum_numbers(s):
"""
Convert a string of numbers into a sum of those numbers.
:param s: A string of numbers, e.g. '1 -2 3.3 4e10'.
:return: The floating-point sum of the numbers in the string.
"""
def convert_s_to_val(s):
"""
Convert a string into a number. Will handle anything that
Python could convert to a float.
:param s: A number as a string, e.g. '123' or '8.3e-18'.
:return: The float value of the string.
"""
if s:
return float(s)
else:
return 0
# These will serve as placeholders.
sum = 0
current = ''
# Iterate over the string character by character.
for c in s:
# If the character is a space, we convert the current `current`
# into its numeric representation.
if c.isspace():
sum += convert_s_to_val(current)
current = ''
# For anything else, we accumulate into `current`.
else:
current = current + c
# Add `current`'s last value to the sum and return.
sum += convert_s_to_val(current)
return sum
就个人而言,我会使用这个单行,但它使用str.split()
:
def sum_numbers(s):
return sum(map(float, s.split()))
答案 2 :(得分:1)
在这个答案的制作中没有使用(也没有受到伤害)名单:
def sum_string(string):
total = 0
if len(string):
j = string.find(" ") % len(string) + 1
total += int(string[:j]) + sum_string(string[j:])
return total
如果字符串比OP指示的更嘈杂,那么这应该更强大:
import re
def sum_string(string):
pattern = re.compile(r"[-+]?\d+")
total = 0
match = pattern.search(string)
while match:
total += int(match.group())
match = pattern.search(string, match.end())
return total
<强>实施例强>
>>> sum_string('34 3 542 11')
590
>>> sum_string(' 34 4 ')
38
>>> sum_string('lksdjfa34adslkfja4adklfja')
38
>>> # and I threw in signs for fun
...
>>> sum_string('34 -2 45 -8 13')
82
>>>
答案 3 :(得分:1)
如果您希望能够处理浮点数和负数:
def sum_numbers(s):
sm = i = 0
while i < len(s):
t = ""
while i < len(s) and not s[i].isspace():
t += s[i]
i += 1
if t:
sm += float(t)
else:
i += 1
return sm
哪种情况适用于所有情况:
In [9]: sum_numbers('34 3 542 11')
Out[9]: 590.0
In [10]: sum_numbers('1.93 -1 23.12 11')
Out[10]: 35.05
In [11]: sum_numbers('')
Out[11]: 0
In [12]: sum_numbers('123456')
Out[12]: 123456.0
或采取切片的变化:
def sum_numbers(s):
prev = sm = i = 0
while i < len(s):
while i < len(s) and not s[i].isspace():
i += 1
if i > prev:
sm += float(s[prev:i])
prev = i
i += 1
return sm
你也可以使用 itertools.groupby ,它不使用任何列表,使用一组允许的字符来分组:
from itertools import groupby
def sum_numbers(s):
allowed = set("0123456789-.")
return sum(float("".join(v)) for k,v in groupby(s, key=allowed.__contains__) if k)
为您提供相同的输出:
In [14]: sum_numbers('34 3 542 11')
Out[14]: 590.0
In [15]: sum_numbers('1.93 -1 23.12 11')
Out[15]: 35.05
In [16]: sum_numbers('')
Out[16]: 0
In [17]: sum_numbers('123456')
Out[17]: 123456.0
如果您只需考虑正面整数,可以使用 str.isdigit 作为关键:
def sum_numbers(s):
return sum(int("".join(v)) for k,v in groupby(s, key=str.isdigit) if k)
答案 4 :(得分:0)
试试这个:
def sum_numbers(s):
sum = 0
#This string will represent each number
number_str = ''
for i in s:
if i == ' ':
#if it is a whitespace it means
#that we have a number so we incease the sum
sum += int(number_str)
number_str = ''
continue
number_str += i
else:
#add the last number
sum += int(number_str)
return sum
答案 5 :(得分:0)
你可以写一个发电机:
def nums(s):
idx=0
while idx<len(s):
ns=''
while idx<len(s) and s[idx].isdigit():
ns+=s[idx]
idx+=1
yield int(ns)
while idx<len(s) and not s[idx].isdigit():
idx+=1
>>> list(nums('34 3 542 11'))
[34, 3, 542, 11]
然后总结一下:
>>> sum(nums('34 3 542 11'))
590
或者,您可以将re.finditer
与正则表达式和生成器构造一起使用:
>>> sum(int(m.group(1)) for m in re.finditer(r'(\d+)', '34 3 542 11'))
590
没有使用名单......
答案 6 :(得分:0)
def sum_numbers(s):
total=0
gt=0 #grand total
l=len(s)
for i in range(l):
if(s[i]!=' '):#find each number
total = int(s[i])+total*10
if(s[i]==' ' or i==l-1):#adding to the grand total and also add the last number
gt+=total
total=0
return gt
print(sum_numbers('1 2 3'))
此处每个子字符串都会转换为数字并添加到授予总计
答案 7 :(得分:0)
如果我们省略事实eval
是evil,我们可以用它来解决这个问题。
def sum_numbers(s):
s = s.replace(' ', '+')
return eval(s)
是的,那很简单。但我不会把这件事投入生产。
确定我们需要测试一下:
from hypothesis import given
import hypothesis.strategies as st
@given(list_num=st.lists(st.integers(), min_size=1))
def test_that_thing(list_num):
assert sum_numbers(' '.join(str(i) for i in list_num)) == sum(list_num)
test_that_thing()
它什么也不提。