Python 任何()

Python 任何(),python,Python,这主要是一个学习Python的练习。我编写此函数是为了测试一个数字是否为素数: def p1(n): for d in xrange(2, int(math.sqrt(n)) + 1): if n % d == 0: return False return True 然后我意识到我可以使用任意()轻松地重写它: 就性能而言,我希望p2比p1快,或者至少和p1一样快,因为any()是内置的,但是对于大的ish素数,p2要慢一些: $ pyt

这主要是一个学习Python的练习。我编写此函数是为了测试一个数字是否为素数:

def p1(n):
    for d in xrange(2, int(math.sqrt(n)) + 1):
        if n % d == 0:
            return False
    return True
然后我意识到我可以使用任意()轻松地重写它:

就性能而言,我希望p2比p1快,或者至少和p1一样快,因为any()是内置的,但是对于大的ish素数,p2要慢一些:

$ python -m timeit -n 100000 -s "import test" "test.p1(999983)"
100000 loops, best of 3: 60.2 usec per loop

$ python -m timeit -n 100000 -s "import test" "test.p2(999983)"
100000 loops, best of 3: 88.1 usec per loop
我在这里是否使用了任何()错误?有没有一种方法可以使用any()编写这个函数,这样就可以自己迭代了

更新:更大素数的数字

$  python -m timeit -n 1000 -s "import test" "test.p1(9999999999971)"
1000 loops, best of 3: 181 msec per loop

$  python -m timeit -n 1000 -s "import test" "test.p2(9999999999971)"
1000 loops, best of 3: 261 msec per loop

性能差异很小,但它存在的原因是与for循环相比,
any
需要构建生成器表达式和额外的函数调用。不过,两者都有相同的行为(快捷方式评估)

随着输入大小的增加,差异不会减小(我错了),因为您使用的是生成器表达式,对其进行迭代需要在其上调用方法(
.next()
)和额外的堆栈帧<当然,代码>任何都是在引擎盖下完成的

for循环在
xrange
对象上迭代
any
在生成器表达式上迭代,生成器表达式本身在
xrange
对象上迭代


无论采用哪种方式,都可以使用生成可读性/可维护性最高的代码。选择其中一个对你正在编写的任何程序的性能影响都很小(如果有的话)。

看,它看起来确实很像你所写的。@rightføld 50%的增长是一个小差别?不,但与你的问题无关,只是出于好奇(和我糟糕的数学技能)请您向我解释一下为什么只需要使用range
xrange(2,int(math.sqrt(n))+1)
?我总是按照
xrange(2,n)
@IanAuld的方式来做,如果
sqrt(n)
上面的
x
会除以
n
,那么另一个因素就是
,到时候你就会找到了。谢谢。我知道它们有相同的行为,只是因为我是Python新手,所以我试图学习内置函数的正确用法。但是对于更大的素数,我并没有看到差异缩小(我将在稍后更新这个问题)。即使是13位数的素数,差异仍然在50%左右(约180ms对约270ms)。我明白你关于可读性的观点,但是对于这个特殊的练习,我更感兴趣的是理解any()的用法。谢谢。这是有道理的。我不同意它对性能没有任何影响。一个实现似乎始终比另一个慢50%,因此根据调用此函数的频率,可能会有显著的性能差异。也就是说,你关于生成器表达式的观点对我来说完全有意义。谢谢好吧,像往常一样,写工作,可读的代码,然后配置和优化。总是按那个顺序;)
$  python -m timeit -n 1000 -s "import test" "test.p1(9999999999971)"
1000 loops, best of 3: 181 msec per loop

$  python -m timeit -n 1000 -s "import test" "test.p2(9999999999971)"
1000 loops, best of 3: 261 msec per loop