如何有效地检查Python中的字符串是否为十六进制

问题描述 投票:0回答:1

我需要检查字符串是否为十六进制。我学会了2种方法-

1。)遍历每个字符

all(c in string.hexdigits for c in s) # Straight forward with no optimizations

2。)使用int()函数检查错误

try:
    int(s, 16)
    return True
except ValueError:
    return False

在第一种情况下,我知道复杂度为O(n)。但是第二个呢?那里的时间复杂度是多少?

python python-internals
1个回答
4
投票

int(s, 16)仍将具有复杂度O(n),其中n == len(s),但两者不能直接比较。 int将以比all更低的级别遍历数据,这速度更快,但是int也会做更多的工作(它实际上必须计算s的整数值)。

那么哪个更快?您必须同时配置两者。

In [1]: s = "783c"

In [2]: import string

In [3]: %timeit all(c in string.hexdigits for c in s)
800 ns ± 3.23 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %%timeit
   ...: try:
   ...:   int(s, 16)
   ...: except ValueError:
   ...:   pass
   ...:
223 ns ± 1.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

看起来像是内部迭代胜出。我也对9位数字的字符串进行了测试,int仍然快4倍。

但是invalid字符串呢?

In [8]: s = 'g'

In [9]: %%timeit
   ...: try:
   ...:   int(s, 16)
   ...: except ValueError:
   ...:   pass
   ...:
1.09 µs ± 2.62 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [10]: %timeit all(c in string.hexdigits for c in s)
580 ns ± 6.55 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

现在,我们基本上正在测试短路带来的好处与捕获异常的代价。如果错误稍后出现在字符串中,该怎么办?

In [11]: s = "738ab89ffg"

In [12]: %timeit all(c in string.hexdigits for c in s)
1.59 µs ± 19.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [13]: %%timeit
    ...: try:
    ...:   int(s, 16)
    ...: except ValueError:
    ...:   pass
    ...:
1.25 µs ± 19.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

现在,我们再次看到内部迭代的好处。

© www.soinside.com 2019 - 2024. All rights reserved.