如何优化计算python列表中的元素

Chr*_*phe 6 python performance list count

这几乎超过了同样的问题在这里,但我问了排序结果的最有效的解决方案.

我有一个列表(大约10个整数在0到12之间随机),例如:

the_list = [5, 7, 6, 5, 5, 4, 4, 7, 5, 4]
Run Code Online (Sandbox Code Playgroud)

我想创建一个函数,该函数返回由第一个元素排序的元组(项目,计数)列表

output = [(4, 3), (5, 4), (6, 1), (7, 2)]
Run Code Online (Sandbox Code Playgroud)

到目前为止我用过:

def dupli(the_list):
    return [(item, the_list.count(item)) for item in sorted(set(the_list))]
Run Code Online (Sandbox Code Playgroud)

但我把这个函数称为几乎是一个时间,我需要像我(python)一样快.因此我的问题是:如何让这个功能减少时间消耗?(内存怎么样?)

我玩了一下,但没有明显的结果:

from timeit import Timer as T
number=10000
setup = "the_list=[5, 7, 6, 5, 5, 4, 4, 7, 5, 4]"

stmt = "[(item, the_list.count(item)) for item in sorted(set(the_list))]"
T(stmt=stmt, setup=setup).timeit(number=number)

Out[230]: 0.058799982070922852

stmt = "L = []; \nfor item in sorted(set(the_list)): \n    L.append((item, the_list.count(item)))"
T(stmt=stmt, setup=setup).timeit(number=number)

Out[233]: 0.065041065216064453

stmt = "[(item, the_list.count(item)) for item in set(sorted(the_list))]"
T(stmt=stmt, setup=setup).timeit(number=number)

Out[236]: 0.098351955413818359
Run Code Online (Sandbox Code Playgroud)

谢谢
Christophe

Ste*_*ski 4

更改排序位置可节省约 20% 的费用。

改变这个:

def dupli(the_list):
    return [(item, the_list.count(item)) for item in sorted(set(the_list))]
Run Code Online (Sandbox Code Playgroud)

对此:

def dupli(the_list):
    count = the_list.count # this optimization added courtesy of Sven's comment
    result = [(item, count(item)) for item in set(the_list)]
    result.sort()
    return result
Run Code Online (Sandbox Code Playgroud)

这样做更快的原因是sorted迭代器必须创建一个临时列表,而对结果进行排序则就地排序。

编辑: 这是另一种方法,比原来的方法快 35%:

def dupli(the_list):
    counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    for n in the_list:
        counts[n] += 1
    return [(i, counts[i]) for i in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) if counts[i]]
Run Code Online (Sandbox Code Playgroud)

注意:您可能想要随机化 的值the_list。我的最终版本dupli使用其他随机数据集进行的测试甚至更快 ( import random; the_list=[random.randint(0,12) for i in xrange(10)])