【问题标题】:fast way to remove lowercase substrings from string?从字符串中删除小写子字符串的快速方法?
【发布时间】:2013-03-04 11:21:52
【问题描述】:

在 Python 中(普通或使用 numpy)从字符串 s 中删除所有小写子字符串的有效方法是什么?

s = "FOObarFOOObBAR"
remove_lower(s) => "FOOFOOBAR"

【问题讨论】:

    标签: python string numpy


    【解决方案1】:

    Python3.x 答案:

    你可以制作一个字符串翻译表。创建转换表后,您可以重复使用它:

    >>> import string
    >>> table = str.maketrans('', '', string.ascii_lowercase)
    >>> s = 'FOObarFOOObBAR'
    >>> s.translate(table)
    'FOOFOOOBAR'
    

    以这种方式使用时,第一个参数值映射到第二个参数值(如果存在)。如果不存在,则假定为恒等映射。第三个参数是要移除的值的集合。


    任何关心的人的旧 python2.x 答案:

    我会使用str.translate。如果您为翻译表传递None,则仅执行删除步骤。在这种情况下,我将ascii_lowercase 作为要删除的字母传递。

    >>> import string
    >>> s = 'FOObarFOOObBAR'
    >>> s.translate(None, string.ascii_lowercase)
    'FOOFOOOBAR'
    

    我怀疑你会找到更快的方法,但如果有人有动力,总有timeit 比较不同的选择:)。

    【讨论】:

    • 字符串模块不是已经弃用了吗?
    • @DiegoHerranz -- 似乎不是。在reference docs 上搜索“depr”并没有出现任何结果。我认为这是一个普遍的谣言,因为其中的大多数方法只是内置 str 类型的别名,因此它们将来可能会被弃用。
    • 我认为不推荐使用的是(函数版本的)方法。例如,在 python 3.3 中,只有 ascii_lowercasepunctuation 这样的常量以及 FormatterTemplate 这样的类。没有rindexsplit
    • 啊,大概就是这样 :-)
    • 这仅适用于字节字符串。如果字符串 s 是 unicode,则上面的代码将失败并显示 TypeError: translate() takes exactly one argument (2 given)。由于字符串在 Python 3 中默认为 unicode,因此这在 Python 3 中不起作用。
    【解决方案2】:

    我的第一个方法是''.join(x for x in s if not x.islower())

    如果您需要速度,请使用 mgilson 答案,它会快很多。

    >>> timeit.timeit("''.join(x for x in 'FOOBarBaz' if not x.islower())")
    3.318969964981079
    
    >>> timeit.timeit("'FOOBarBaz'.translate(None, string.ascii_lowercase)", "import string")
    0.5369198322296143
    
    >>> timeit.timeit("re.sub('[a-z]', '', 'FOOBarBaz')", "import re")
    3.631659984588623
    
    >>> timeit.timeit("r.sub('', 'FOOBarBaz')", "import re; r = re.compile('[a-z]')")
    1.9642360210418701
    
    >>> timeit.timeit("''.join(x for x in 'FOOBarBaz' if x not in lowercase)", "lowercase = set('abcdefghijklmnopqrstuvwxyz')")
    2.9605889320373535
    

    【讨论】:

    • +1 对当前的两个答案,但我更喜欢这个有两个原因。 #1 是我一直使用 genexps,所以我不必考虑语法。我永远不记得translatemaketrans 是如何工作的。 #2 是这种方法更稳健:如果需求稍有变化,则更有可能存活。
    • @DSM -- 我也很难记住translatemaketrans 是如何工作的,但我已经习惯了。烦人的部分是直到python3.x才没有str.maketrans,所以如果你真的想使用翻译表,你实际上需要import字符串。
    • 如果您创建一个小写字符的本地set,看看性能如何变化可能会很有趣。然后你可以测试集合中的成员而不是查看x.islower()。当然,除非您可以预先计算该集合,否则您可能一无所获。您不想在每次迭代时都这样做。为了加快大约 30% 的速度(根据我的经验——没有实际时间),您还可以使用 list-comp 代替生成器表达式。
    【解决方案3】:
    import re
    
    remove_lower = lambda text: re.sub('[a-z]', '', text)
    
    s = "FOObarFOOObBAR"
    s = remove_lower(s)
    
    print(s)
    

    【讨论】:

      猜你喜欢
      • 2015-11-27
      • 1970-01-01
      • 1970-01-01
      • 2019-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多