Python - 在字符串中查找数字

15
def get_digits(str1):
    c = ""

    for i in str1:
        if i.isdigit():
            c += i
            return c
上面是我使用的代码,问题是它只返回字符串的第一个数字。为了解决这个问题,我必须保留for循环和return语句。有人知道如何修复吗?
谢谢。

这是作业吗?如果是,请将其标记为作业。 - mgilson
我在我的答案中添加了基准测试。 - Tarantula
6个回答

28

就像其他人所说,你的缩进存在语义问题,但你不必编写这样一个函数来解决它,更加Pythonic的方法是:

def get_digits(text):
    return filter(str.isdigit, text)

关于解释器:

>>> filter(str.isdigit, "lol123")
'123'

一些建议

当他人提出“更快”的方法时,请始终自行进行测试:

from timeit import Timer

def get_digits1(text):
    c = ""
    for i in text:
        if i.isdigit():
            c += i
    return c

def get_digits2(text):
    return filter(str.isdigit, text)

def get_digits3(text):
    return ''.join(c for c in text if c.isdigit())

if __name__ == '__main__':
    count = 5000000
    t = Timer("get_digits1('abcdef123456789ghijklmnopq123456789')", "from __main__ import get_digits1")
    print t.timeit(number=count)

    t = Timer("get_digits2('abcdef123456789ghijklmnopq123456789')", "from __main__ import get_digits2")
    print t.timeit(number=count)

    t = Timer("get_digits3('abcdef123456789ghijklmnopq123456789')", "from __main__ import get_digits3")
    print t.timeit(number=count)



~# python tit.py
19.990989106  # Your original solution
16.7035926379 # My solution
24.8638381019 # Accepted solution

2
在Python 3中,您需要执行''.join(filter(lambda x: x.isdigit(), "lol123")),请参见https://dev59.com/xHM_5IYBdhLWcg3wRw11#1450900。 - asmaier
请注意:只有在调用 isdigit()(注意括号)时才需要使用lambda。如上所示使用str.isdigit即可正常工作。 - JRiggles

10

你的缩进有点混乱(在Python中,缩进非常重要)。更好的方式是:

def get_digits(str1):
    c = ""
    for i in str1:
        if i.isdigit():
            c += i
    return c

使用生成器表达式的一种更短、更快的解决方案:

''.join(c for c in my_string if c.isdigit())

2
那是一个生成器表达式,而不是列表推导,但无论哪种方式都要为它加上+1。 - lvc
除了实际的 PEP,是否有更好的文档来介绍生成器表达式? - Benjamin Wohlwend
1
我已经编辑了你的答案,链接到Python教程的相关部分;还有语言参考 - lvc
一个更“高级”的版本是用yield语句替换连接操作。不过,filter方法更加优雅。 - fbstj
你的解决方案不仅不更快,反而更慢了。在这里使用生成器表达式没有任何意义,因为你返回的是整个结果而不是产生数字,这是不合理的。请查看我的答案,并进行基准测试比较两种解决方案。 - Tarantula

2

这是因为你的return语句在for循环内部,所以它会在第一个true的if条件后返回并停止执行。

  def get_digits(str1):
      c = ""
      for i in str1:
        if i.isdigit():
            c += i
      return c

1

存在一个缩进问题,当它找到第一个数字时就会出现,因为当前的缩进被解释为if语句内的语句, 它需要与for语句平行 才能被视为在for语句之外。

def get_digits(str1):
    c = ""

    for i in str1:
        if i.isdigit():
            c += i

    return c

digits = get_digits("abd1m4m3m22mmmbb4")
print(digits)

你错误代码的花括号等效形式为:

def get_digits(str1){
    c = ""

    for i in str1 {
        if i.isdigit(){
            c += i
            return c    # Notice the error here
        }
    }
}

当代码被更正以使返回语句与 for 对齐时,等效的代码如下:

def get_digits(str1){
        c = ""

        for i in str1 {
            if i.isdigit(){
                c += i               
            }
        }
        return c    # Correct as required
    }

1

你的代码几乎没问题,除了需要将return语句移动到for循环的层级。

def get_digits(str1):
    c = ""
    for i in str1:
        if i.isdigit():
            c += i
    return c   ## <--- moved to correct level

所以,现在:

get_digits('this35ad77asd5')

产生:
'35775'

解释:

以前,您的函数仅返回第一个数字,因为当它找到一个数字时,if语句被执行,return也被执行(导致您从函数中返回,这意味着您没有继续查找字符串)。

在Python中,空格/缩进真的很重要,正如您所看到的(与许多其他语言不同)。


1

当然它只返回第一个数字,你明确告诉Python一旦有数字就立即返回。

更改return语句的缩进,它应该可以工作:

def get_digits(str1):
    c = ""

    for i in str1:
        if i.isdigit():
            c += i

    # Note the indentation here
    return c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接