想要改善这个脚本

时间:2018-10-13 08:53:08

标签: python

我正在查看一些已保存的脚本,并遇到了该特定脚本。我觉得无需使用所有大小写字母就可以改进它,有什么建议吗?我当时在考虑使用str.lower,但并没有真正了解如何实现

def all_but_not_numbs(s: str) -> int:
    """
    >>> all_but_not_numbs('asd123')
    3
    >>> all_but_not_numbs('E.666')
    2
    """

    num_letters = 0

    for char in s: 
        if char in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.,':
            num_letters = num_letters + 1
    return num_letters

4 个答案:

答案 0 :(得分:3)

使用str.lower,可以将要测试的字符小写,因此不需要大写字母。 .,的字符不受lower的影响。另外,将sum与生成器表达式一起使用,可以使代码更紧凑,(IMHO)更具可读性。

>>> letters = "abcdefghijklmnopqrstuvwxyz,."
>>> s = 'E.666'
>>> sum(1 for c in s if c.lower() in letters)
2

或者您可以使用string模块中定义的ascii_letters

>>> import string
>>> letters = string.ascii_letters + ",."
>>> sum(1 for c in s if c in letters)
2

在这两种情况下,in检查都是线性的(对于k个“好”字母为O(k))。对于这么短的字母列表来说,这应该不是问题,但是为了进一步改进它,您可以将letters变成set,以便使in的校验为O(1)

>>> letters = set(letters)

答案 1 :(得分:2)

使用regex查找所有字母和点并取其长度:

import re

s = 'asd123'
print(len(re.findall(r'[a-zA-Z\.]', s)))
# 3

答案 2 :(得分:0)

您还可以使用以下方法,基本上是去除数字并使用len来计算剩余字符数:

>>> s
'asd123'
>>> to_strip = '0123456789'
>>> len(s.strip(to_strip))
3

或使用string.digits模块中的string

>>> s
'asd123'
>>> len(s.strip(string.digits))
3

编辑:在tobias_k评论之后,我建议以下内容与奥斯丁的答案类似,但采用不同的方法:

>>> s = 'abced@#$%123'
>>>
>>> import re
>>>
>>> to_strip
'0123456789'
>>> re.findall('[^{}]'.format(to_strip), s)
['a', 'b', 'c', 'e', 'd', '@', '#', '$', '%']
>>> len(re.findall('[^{}]'.format(to_strip), s))
9

它说要查找除(^)以外的所有字符(^),即数字。

答案 3 :(得分:0)

我使用了s.isalpha()s.upper.isupper()ch in '.'(不需要,):

现在,我的问题是关于Python为什么说我的行if ch.isalpha():不一致? 错误:builtins.TabError: inconsistent use of tabs and spaces in indentation

num = 0
for ch in s:
    if ch.isalpha():
        num = num + 1
    elif ch.upper.isupper():
        num = num + 1
    elif ch in '.':
        num = num + 1
return num