我有一个包含数字的字符串。我想检查字符串是否包含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 :(得分:7)
您的代码性能不佳的几个原因:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
。in
非常昂贵(O(n)
)。而不是in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
更喜欢in {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
。集合上的in
要便宜得多(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
答案 1 :(得分:2)
我就是这样做的:
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
运行
num = "31586055033755830765"
print(bool(not check_num(num))) # False
此代码一次检查一个数字,如果找到所有数字,则退出循环。
运行时间的大小为the other answer:
import string
import random
num=str(random.getrandbits(256))
In [35]: %timeit set(num) == set(string.digits)
100000 loops, best of 3: 9.89 µs per loop
In [36]: %timeit bool(not check_num(num))
100000 loops, best of 3: 14.9 µs per loop
对于平均情况下的非常大的数字(当数字包含均匀分布的数字时)它稍微好一些
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
答案 2 :(得分:1)
您也可以在此处使用all()
:
>>> from string import digits
>>> numbers = set(digits)
>>> num = '31586055033755830765'
>>> all(x in numbers for x in num)
True
答案 3 :(得分:0)
您可以使用散列。假设你的字符串只有数字
num = "31586055033755830765"
temp = dict()
for i in num:
if not i in a:
a[i] = True
if (len(a)!=10):
sys.exit(1)
答案 4 :(得分:0)
如果您的字符串还包含与数字不同的字符串,则为
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
答案 5 :(得分:-1)
你可以试试这个:
test='1234567890'
print(any(list(filter(lambda x:x not in "31586055033755830765" ,test))))
如果result为True,则表示所有int都不在秒中,如果result为false,则表示所有int都在字符串中。
输出:
True
因为
['2', '4', '9'] are not in "31586055033755830765"