在我正在尝试编写的函数中,用户输入一堆数字,例如“648392”。 我把这个字符串变成这样的列表:['6','4','8','3','9','2']。
我希望能够对这些数字进行求和,因此我将列表中的数字转换为整数而不是字符串。这一切都运行良好,但我也希望用户能够输入字母,然后我只是将它们从列表中删除 - 这就是我被困住的地方。例如,用户输入“6483A2”。
我无法检查元素是否是带有isDigit的数字,因为元素显然必须首先是整数,并且我无法将列表中的元素转换为整数,因为某些元素是字母。我确信这是一个简单的解决方案,但我在python中非常糟糕,所以任何帮助都会非常感激!
答案 0 :(得分:6)
您可以使用str.translate
过滤掉字母:
>>> from string import letters
>>> strs = "6483A2"
>>> strs.translate(None, letters)
'64832'
无需将字符串转换为列表,您可以遍历字符串本身。
使用str.join
,str.isdigit
和列表理解:
>>> ''.join([c for c in strs if c.isdigit()])
'64832'
或者你想要sum
数字:
sum(int(c) for c in strs if c.isdigit())
小字符串:
>>> strs = "6483A2"
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100000 loops, best of 3: 9.19 us per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
100000 loops, best of 3: 10.1 us per loop
大字符串:
>>> strs = "6483A2"*1000
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100 loops, best of 3: 5.47 ms per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
100 loops, best of 3: 8.54 ms per loop
最糟糕的是,所有信件:
>>> strs = "A"*100
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100000 loops, best of 3: 2.53 us per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
10000 loops, best of 3: 24.8 us per loop
>>> strs = "A"*1000
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100000 loops, best of 3: 7.34 us per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
1000 loops, best of 3: 210 us per loop
答案 1 :(得分:3)
您可以使用filter
函数或理解来过滤任何可迭代(包括字符串)中的内容。例如,以下任何一个:
digits = filter(str.isdigit, input_string)
digits = (character for character in input_string if character.isdigit())
...会给你一个可迭代的数字。如果您想将每个转换为数字,则其中任何一个都可以执行此操作:
numbers = map(int, filter(str.isdigit, input_string))
numbers = (int(character) for character in input_string if character.isdigit())
因此,要获取所有数字的总和,跳过字母,只需将其中任何一个传递给sum
函数:
total = sum(map(int, filter(str.isdigit, input_string)))
total = sum(int(character) for character in input_string if character.isdigit())
从你的上一段开始:
我无法检查元素是否是带有isDigit的数字,因为元素显然必须首先是整数,并且我无法将列表中的元素转换为整数
首先,它是isdigit
,而不是isDigit
。其次,isdigit
是一个关于字符串而不是整数的方法,所以你认为你不能在字符串上调用它是错误的。实际上,在将字符串转换为整数之前,必须在字符串上调用它。
但这确实提出了另一种选择。在Python中,它通常是Easier to Ask Forgiveness than Permission。我们可以尝试将它转换为int,然后处理可能的失败,而不是弄清楚我们是否可以将每个字母转换为int,然后再进行转换。例如:
def get_numbers(input_string):
for character in input_string:
try:
yield int(character)
except TypeError:
pass
现在,它只是:
total = sum(get_numbers(input_string))
答案 2 :(得分:2)
你可以通过理解来做到这一点:
>>> s = "6483A2"
>>> [int(c) for c in s if c.isdigit()]
[6, 4, 8, 3, 2]
>>> sum(int(c) for c in s if c.isdigit())
23
如果你想直接从混合字符串到只有整数的列表,这种方法很好,这可能是你的目标。
答案 3 :(得分:1)
您可以使用generator expression并将其放入sum
。
>>> import string
>>> s
'6483A2'
>>> sum(int(x) for x in list(s) if x in string.digits)
23
如果没有其他模块要导入,请使用isdigit
:
sum(int(x) for x in list(s) if x.isdigit())
答案 4 :(得分:1)
>>> a = "hello123987io"
>>> b = "khj7djksh787"
>>> sum([int(letter) for letter in b if letter.isdigit()])
29
>>> sum([int(letter) for letter in a if letter.isdigit()])
30
>>> def getInputAndSum(userInput):
... """ returns a tuple with the input string and its sum """
... return userInput, sum([int(letter) for letter in userInput if letter.isdigit()])
...
>>> getInputAndSum("Th1s1550mesum")
('Th1s1550mesum', 12)
答案 5 :(得分:1)
只是贡献一点,如果你想要聚合总和,你可以这样做:
x = "6483A2"
sum(map(int, filter(str.isdigit, x)))
>>>23
如果您需要仅用于其他目的的整数列表或其他类型的sum
,请将其保留在map
中:
map(int, filter(str.isdigit, x))
>>>[6, 4, 8, 3, 2]
注意:关于string.letters
方法。 letters
依赖于locale
,所以:
import locale, string
locale.setlocale(locale.LC_ALL, 'es_ES') # or 'esp_esp' if you're on Windows
string.letters
>>> "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzŠŚŽšśžźŞµşŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőöřůúűüýţ˙"
虽然如上所述,我建议regex
用于此案例:)
很高兴合作:D
答案 6 :(得分:0)
虽然你可以用各种方式过滤掉字母,但是让译员决定什么可以被解释为数字和什么不可以。所以即使它不是单行,你可能更喜欢这种方法:
aninput = "648392A0&sle4"
def discard_non_ints(itbl, rdx=10):
for d in itbl:
try:
yield(int(d, rdx))
except ValueError:
pass
sum(discard_non_ints(aninput))
36
这种方法特别好用的是它可以灵活地包含非十进制数字。想要求所有十六进制数字?
sum(discard_non_ints('deadbeforenoon', 16))
104