如何优化以下python片段?

时间:2017-04-06 08:29:31

标签: python

以下代码片段用于返回不包含重复数字的数字的数字。

例如,如果输入为7,则程序应返回7个计数(1,2,3,4,5,6,7)的数字计数,然后输出应为7

如果输入为23,则程序应返回23次数(1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17,18,19,20,21,23)的计数,此处计数排除了数字,如11,22,输出应为21

要优化此代码,我该怎么办?

def nonrep1(n):
    return sum(all(c != d for c, d in zip(str(i), str(i)[1:])) for i in xrange(1, n+1))

我必须优化此代码,我该怎么做?

测试用例1:

  

简单输入:

7
     

简单输出:

7

测试用例2:

  

简单输入:

3456
     

简单输出:

2562

1 个答案:

答案 0 :(得分:-1)

总是惊讶于pythonic'解决方案可以。以下使用cython加速80倍:

from libc.math cimport log10
from cython.operator cimport preincrement as preinc
import cython

@cython.cdivision(True)
cdef int add_number(int i):
    cdef int cur_last = i % 10, next_last = 0
    cdef int cur_val = i / 10

    cdef int jj = 0
    for jj in xrange(int(log10(cur_val) + 1)):
        next_last = cur_val % 10
        if next_last == cur_last:
            return 0
        cur_val /= 10
        cur_last = next_last

    return 1

cpdef int cython_nonrep1(int n):
    cdef int s = 0
    cdef int i = 0
    if n < 10:
        return n

    for i in xrange(10, n+1):
        s += add_number(i)
    return s

要使用它,请将其保存在.pyx文件中并使用pyximport(或使用distutils等构建它)

一些基准:

%timeit nonrep1(3456)
100 loops, best of 3: 4.92 ms per loop


% timeit cython_nonrep1(3456)
10000 loops, best of 3: 63.4 µs per loop