我如何加快这段代码?

时间:2016-05-15 22:32:55

标签: python performance python-2.7

我有一个函数,它以列表作为参数:

def f(x):
    for i,j in enumerate(x):
        if j == '0':
            x[i] = '1'
        else:
            x[i] = '0'
    return ''.join(x)

此功能的用法如下:

while len(x) <= n:
    x = ''.join([x,f([i for i in x])])

如果n&gt;此代码暂停10000000.怎么可以改进? 以下是cProfile所说的内容:

         98 function calls in 3.974 seconds

   Ordered by: call count

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       48    0.235    0.005    0.235    0.005 {method 'join' of 'str' objects}
   25    0.000    0.000    0.000    0.000 {len}
   24    3.740    0.156    3.965    0.165 1:9(f)
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

2 个答案:

答案 0 :(得分:1)

假设我正确理解了你的目标,这里有一些你可以尝试的方法。我会让你做时间。

>>> print x
11001011
>>> print ''.join('1' if c == '0' else '0' for c in x)
00110100
>>> print ''.join(str(int(c == '0')) for c in x)
00110100
>>> print ''.join(map(str, map(int, map('0'.__eq__, x))))
00110100
>>> from itertools import imap
>>> print ''.join(map(str, imap(int, imap('0'.__eq__, x))))
00110100
>>> y = bin(int(x, 2) ^ ((1 << len(x)) - 1))[2:]
>>> print y
110100
>>> print '0' * (len(x) - len(y)) + y
00110100

最后一个只有在严格使用1和0时才有效。实际上使用~可能会更好,但我现在需要上床睡觉。 Google“python flip bits”。

答案 1 :(得分:0)

您的版本:

def f(x):
    for i,j in enumerate(x):
        if j == '0':
            x[i] = '1'
        else:
            x[i] = '0'
    return ''.join(x)

​
def assemble(x, n):
    while len(x) <= n:
        x = ''.join([x,f([i for i in x])])
    return x

更快的版本1:

def assemble_fast1(x, n):
    res = list(x)
    while len(res) <= n:
        res.extend(['01'[c=='0'] for c in res])
    return ''.join(res)

更快的版本2:

def assemble_fast2(x, n):
    res = list(x)
    while len(res) <= n:
        res.extend(['1' if c == '0' else '0' for c in res])
    return ''.join(res)

一些时间:

In [293]:
n = int(1e7)
x = '101011'
assemble_fast1(x, n) == assemble_fast2(x, n) == assemble(x, n)
Out[293]:
True

In [294]:
%timeit assemble_fast1(x, n)
1 loops, best of 3: 1.85 s per loop

In [295]:
%timeit assemble_fast2(x, n)
1 loops, best of 3: 1.67 s per loop

In [296]:
%timeit assemble(x, n)
1 loops, best of 3: 3.15 s per loop

所以assemble_fast2大约是你的版本的两倍。