Python 检查字符串中所有数字的更快方法

Python 检查字符串中所有数字的更快方法,python,python-3.x,Python,Python 3.x,我有一个保存数字的字符串。我想检查字符串是否包含0-9之间的所有数字。目前,我检查的方式非常慢,对于大字符串来说肯定是无用的。下面是我的代码: import sys # check if all numbers (0-9) exist in a string num = "31586055033755830765" for i in num: if int(i) not in [0, 1, 2 ,3 ,4 ,5 ,6, 7, 8, 9]: print("The stri

我有一个保存数字的字符串。我想检查字符串是否包含0-9之间的所有数字。目前,我检查的方式非常慢,对于大字符串来说肯定是无用的。下面是我的代码:

import sys

# check if all numbers (0-9) exist in a string
num = "31586055033755830765"
for i in num:
    if int(i) not in [0, 1, 2 ,3 ,4 ,5 ,6, 7, 8, 9]:
        print("The string doesn't have all the numbers")
        sys.exit(1)

代码工作正常,但速度相当慢。有没有更快的方法来完成任务?

代码性能差的几个原因:

  • 每次迭代它都会创建一个新列表(
    [0,1,2,3,4,5,6,7,8,9]
  • 列表中的
    非常昂贵(
    O(n)
    )。而不是[0,1,2,3,4,5,6,7,8,9]中的
    更喜欢{0,1,2,3,4,5,6,7,8,9}中的
    <在电视机上使用
    的code>要便宜得多(
    O(1)
  • 它将
    num
    中的每个字符转换为整数(函数调用+转换本身所需的时间)。相反,您可以将数字作为字符串进行比较:

    if i not in {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
    
这些更改将提高代码的性能,但您可以使用完全不同、更短、更快的方法,只使用集合:

import string

num = '31586055033755830765'

print(set(num) == set(string.digits))
# False

print(set('1234567890') == set(string.digits))
# True

您可以使用散列。假设字符串只有数字

num = "31586055033755830765"
temp = dict()
for i in num:
    if not i in a:
       a[i] = True
if (len(a)!=10):
    sys.exit(1)

我会这样做:

def check_num(num):
    not_found="0123456789"
    for i in num:
        if i in not_found:
            not_found = not_found.replace(i, '')
            if not not_found:
                break
    return not_found

此代码一次检查一个数字,如果找到所有数字,则退出循环

运行时间的数量级为:

对于平均情况下的非常大的数字(当数字包含均匀分布的数字时),它稍微好一些

In [47]: num=str(random.getrandbits(2048))

In [48]: %timeit bool(not check_num(num))
100000 loops, best of 3: 15.8 µs per loop

In [49]: %timeit set(num) == set(string.digits)
10000 loops, best of 3: 37.2 µs per loop

如果字符串还包含与数字不同的字符串,则为版本:

import string

num = 'abc0123456789'

print(set(num) == set(string.digits))
# False

all_numbers = set(string.digits)
found = False
for n in num:
    all_numbers.discard(n)
    if not all_numbers:
        found = True
        break
print(found)
# True
您也可以在此处使用
all()

>>> from string import digits
>>> numbers = set(digits)
>>> num = '31586055033755830765'
>>> all(x in numbers for x in num)
True
您可以尝试以下方法:

test='1234567890'
print(any(list(filter(lambda x:x not in "31586055033755830765" ,test))))
若结果为True,则表示所有int都不在秒中;若结果为false,则表示所有int都在字符串中

输出:

True
因为

['2', '4', '9'] are not in "31586055033755830765"

@DeepSpace嘿,感谢您的代码审查和其他提示!顺便说一句,如果len(set(num))=10:,你之前发布的答案不是也更快吗?@SouvikRay它更快,但是错误的:)
len(set('abcdefghij'))==10#真的
@DeepSpace糟糕!我没想过!再次感谢!昨天的这一条是重复的:
notx-in-y
在Python中总是错误的-使用
x-not-in-y
True
['2', '4', '9'] are not in "31586055033755830765"