我被困住了:如何解决执行速度慢的问题?

时间:2020-10-21 08:43:10

标签: python python-3.x

我正在精通Python核心工具。

以下代码旨在列出8位字节的所有可能排列;照原样,我已经等待了将近10分钟,并且代码仍然继续执行:

def duplicateList(obj):
    res = []

    for i in range(len(obj)):
        for j in range(len(obj)):
            if obj[i] == obj[j]:
                if obj[i] not in res:
                    res.append(obj[i])
    return res

def permutation(obj):
    if not obj:
        yield obj
    else:
        for i in range(len(obj)):
            others = obj[:i] + obj[i+1:]
            for j in permutation(others):
                yield obj[i:i+1] + j

def permMain(n):
    start = [0] * n
    d = [start[:]]

    for i in range(len(start)):
        if start[i] == 0:
            start[i] = 1
            d.extend(list(permutation(start)))
    return duplicateList(d)

perm = permMain(8)

print('%-13s | %5s' % ('Result lists', 'Len of lists'))

for l in range(len(perm)):
    if l == 0:
        print('%-13s | %-5s' % (perm[l], len(perm)))
    else:
        print('%-13s |' % (perm[l]))

我想减少执行的等待时间。有什么办法吗?

谢谢

修改: 我找到了答案部分中提供的解决方案的替代方法,但是比product的工作量更多,工作速度也更慢。尽管如此,还是可以选择:

from itertools import product

def duplicateList(obj):
    d = []

    for i in obj:
        if i not in d:
            d.append(i)
            yield i

def permutation(obj):
    if not obj:
        yield obj
    else:
        for i in range(len(obj)):
            others = obj[:i] + obj[i+1:]
            for j in permutation(others):
                yield obj[i:i+1] + j

def permMain(n):
    obj = [0] * n

    for i in range(len(obj)+1):
        if not any(obj):
            yield obj[:]
            obj[i] = 1
        else:
            for j in duplicateList(permutation(obj)):
                yield j
            try:
                obj[i] = 1
            except IndexError:
                break

x = sorted(permMain(8))
y = sorted([list(z) for z in product((0, 1), repeat=8)])

def printer():
    flag = 1

    print('|{!s:^24} | {!s:^23}|'.format('permMain', 'product'))

    for i, j in zip(x, y):
        if i == j: 
            continue
        else:
            flag = 0

    if flag:
        print('|{!s:^50}|'.format('permMain equals product'))

printer()

结果如下:

|        permMain         |         product        |
|             permMain equals product              |
[Finished in 2.3s]

1 个答案:

答案 0 :(得分:2)

我有一个建议给您:不要重新编码/重新开发已经存在的内容。 python的强大功能来自经常被很好地编写,记录和优化的库。

例如,要生成大小为8的01的所有可能的设置:

from itertools import product
list(product((0, 1), repeat=8))

itertools比您的尝试要优化得多:

%timeit list(product((0, 1), repeat=8))
11.3 µs ± 265 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)