有没有更快的方法来浏览大量清单?

时间:2019-03-12 09:44:08

标签: python

我的目标是创建一个将列表作为输入的函数,并以sum(list)为最小值的方式更改该列表。

该函数还接收一个int k;该函数将执行kceil(num(i)/2)次,其中i应该是max(list)以获得最小和。

我正在尝试提高大型列表的搜索结果速度,但是我不能使用numpy。所以对于7,20,10和k = 4结果列表= 14

def minmin(list, k):
    for i in range(k):
        maxind = list.index(max(list))
        maxnum = math.ceil(list[maxind] / 2)
        list[maxind] = maxnum

    return sum(list)

1 个答案:

答案 0 :(得分:0)

鉴于您的解释和限制,没有什么可以改善的;您已经在使用list.index()max(),并利用了内置C实现的所有优势。

唯一不同的是临时变量的分配和对math.ceil()的调用;阅读here,以了解ceil()的替代方法。

另一种可能性是按降序对列表进行排序,以便搜索能更快地找到元素。

这里是一个稍微改进的版本; f1是您的版本,另一个是我的建议。

def f1(input_list, repetitions):
    input_list = list(input_list)

    for _ in range(repetitions):
        idx = input_list.index(max(input_list))
        new_num = math.ceil(input_list[idx] / 2)
        input_list[idx] = new_num

    return sum(input_list)


def f2(input_list, repetitions):
    input_list = list(input_list)
    input_list.sort(reverse=True)

    for _ in range(repetitions):
        idx = input_list.index(max(input_list))
        input_list[idx] = ((input_list[idx] + 1) // 2)

    return sum(input_list)

用于比较持续时间并确保结果相同的代码:

import random
import timeit

for exp_n in range(2, 5):
    n = 10**exp_n
    numbers = [random.randint(1, 9999) for _ in range(n)]

    for exp_k in range(2, 5):
        k = 10**exp_k

        t1 = timeit.timeit(
            'f(numbers, k)', 'from __main__ import numbers, k, f1 as f',
            number=10)
        t2 = timeit.timeit(
            'f(numbers, k)', 'from __main__ import numbers, k, f2 as f',
            number=10)

        print('n {:10,d} | k {:10,d} | {:10.4f} | {:10.4f} | best f{}'.format(
            n, k, t1, t2, '1' if t1 < t2 else '2'))
        assert f1(numbers, k) == f2(numbers, k)

结果是(在Python 3.6上使用Ubuntu):

n        100 | k        100 |     0.0027 |     0.0025 | best f2
n        100 | k      1,000 |     0.0280 |     0.0251 | best f2
n        100 | k     10,000 |     0.2097 |     0.1872 | best f2
n      1,000 | k        100 |     0.0232 |     0.0190 | best f2
n      1,000 | k      1,000 |     0.2295 |     0.2009 | best f2
n      1,000 | k     10,000 |     2.2607 |     2.1653 | best f2
n     10,000 | k        100 |     0.2139 |     0.1903 | best f2
n     10,000 | k      1,000 |     2.1379 |     1.6530 | best f2
n     10,000 | k     10,000 |    21.3588 |    18.8767 | best f2

如您所见,反向排序确实有帮助。