【问题标题】:How to check if a string contains only characters from a given set in python如何检查字符串是否仅包含python中给定集合中的字符
【发布时间】:2013-12-22 03:40:14
【问题描述】:

我有一个用户输入的多项式,我只想在字符串1234567890^-+x 中只有字符的情况下使用它。

如何在不使用外部软件包的情况下检查它是否存在?我只想使用内置的 Python 2.5 函数。

我正在编写一个无需外部包即可在任何 Mac 上运行的程序。

【问题讨论】:

    标签: python string python-2.5


    【解决方案1】:

    这里有一些奇怪的 ;-) 方法:

    good = set('1234567890^-+x')
    
    if set(input_string) <= good:
        # it's good
    else:
        # it's bad
    

    if input_string.strip('1234567890^-+x'):
        # it's bad!
    else:
        # it's good
    

    【讨论】:

    • 我喜欢集合子集方法 :-) 想试试timeit 吗?
    • @MartijnPieters,没有机会 - 有很多方法可以做到这一点,我不想花半个小时来整理它们;-)
    • @user2357112,只是因为我不记得 .issuperset() 做了什么,确切地说,没有查一下 :-( 但我马上就明白了 &lt;=,正如 Martijn 所说,他们是最后还是一样。.issuperset() 可能会因为方法查找费用而变慢。
    • @MartijnPieters,当然,但是如果不查找方法,我永远记不起哪个&lt;=和哪个&gt;=。所以我避开他们。 &lt;=&gt;= 对我来说很明显。
    • @MartijnPieters:issuperset 会...等等,显然它不会短路。我认为它可以在不从input_string 构建集合的情况下进行测试,但是当我几秒钟前尝试{0}.issuperset(xrange(1000000000)) 时,它开始以一种似乎表明它将输入转换为集合的方式消耗内存。我想没有性能优势。
    【解决方案2】:

    使用正则表达式:

    import re
    
    if re.match('^[-0-9^+x]*$', text):
        # Valid input
    

    re 模块随 Python 2.5 一起提供,是您最快的选择。

    演示:

    >>> re.match('^[-0-9^+x]*$', '1x2^4-2')
    <_sre.SRE_Match object at 0x10f0b6780>
    

    【讨论】:

      【解决方案3】:
      1. 您可以将有效字符转换为 set,因为集合提供了更快的查找速度
      2. 那么你可以像这样使用all函数

        valid_chars = set("1234567890^-+x")  # Converting to a set
        if all(char in valid_chars for char in input_string):
            # Do stuff if input is valid
        
      3. 我们也可以将输入字符串转换为一个集合,并检查输入字符串中的所有字符是否都在有效列表中。

        valid_chars = set("1234567890^-+x")  # Converting to a set
        if set(input_string).issubset(valid_chars):
            # Do stuff if input is valid
        

      【讨论】:

      • Set 有一个issuperset 方法。
      • @user2357112 请检查我的答案,我用过issubset
      • 这不是将字符串转换为集合的语法;你想要set("1234567890^-+x")。 (为什么我先看到另一件事?)
      • @user2357112 这叫做集合理解。
      • 不,不是。这是一个包含 1 个元素的集合文字。
      【解决方案4】:

      只需将字符串都转换为 set 并检查 input_set is subset of good_set 如下:

      >>> good_set = set('1234567890^-+x')
      >>> input_set1 = set('xajfb123')
      >>> input_set2 = set('122-32+x')
      >>> input_set1.issubset(good_set)
      False
      >>> input_set2.issubset(good_set)
      True
      >>>
      

      【讨论】:

        【解决方案5】:

        另一种方法,现在使用string.translate()

        >>> import string
        >>> all_chars = string.maketrans('', '')
        >>> has_only = lambda s, valid_chars: not s.translate(all_chars, valid_chars)
        >>> has_only("abc", "1234567890^-+x.")
        False
        >>> has_only("x^2", "1234567890^-+x.")
        True
        

        这不是最易读的方式。 如果你需要它,它应该是最快的之一。

        【讨论】:

        • 您可以将None 作为第一个参数传递给translate()
        • 还有人要检查 Python 2.5 吗? LOL ;-) 它适用于所有 current Pythons :-)
        【解决方案6】:
        whitelist = '1234567890^-+x'
        
        str = 'x^2+2x+1'
        min([ch in whitelist for ch in str])
        True
        
        
        str='x**2 + 1' 
        min([ch in whitelist for ch in str])
        False
        

        【讨论】:

        • min() 几乎不是这个任务的最佳函数。
        • 同意一切都是最好的选择。其他语言的宿醉。
        猜你喜欢
        • 2018-12-25
        • 2019-05-19
        • 2018-06-14
        • 1970-01-01
        • 1970-01-01
        • 2014-10-07
        • 1970-01-01
        • 2011-03-18
        • 2012-02-11
        相关资源
        最近更新 更多