Skip to main content
 首页 » 编程设计

python之Python 中的容器列表 : standard list vs numpy array

2025年05月04日10bluestorm

我正在编写一些需要存储和访问不同类型元素列表的 python 代码。此列表的每个元素都属于不同的类类型。例如:

def file_len(fname): 
    i = 0 
    with open(fname) as f: 
        for i, l in enumerate(f): 
            pass 
    return i + 1 
 
element_list = [ ] 
data = np.loadtxt(filename) 
 
 
if file_len(filename) == 1 :  
            data = np.loadtxt(filename) 
            param1 = data[0] 
            param2 = data[1] 
            element_list.append(Class1.Class1(param1,param2)) 
else: 
    for field in data: 
                    param1 = field[0] 
                    param2 = field[1] 
                    element_list.append(Class1.Class1(param1, param2) 

稍后我将需要多次访问插入到 element_list 的 Class1 中的方法,但不需要修改列表:

for i in xrange(10000): 
    for element in element_list: 
        result += element.calculate_result(i).real #the results will be complex 

有没有一种有效的方法来做到这一点?

谢谢!

请您参考如下方法:

这不是一个完整的答案,但我发现了两件事我可以贡献。

这里是 file_len() 的改进版本。如果文件长度为零,则此函数将返回 0。您的函数为零长度文件返回 1,为只有一行的文件返回 1。

def file_len(fname): 
    i = 0 
    with open(fname) as f: 
        for i, l in enumerate(f, 1): 
            pass 
    return i 

这是执行计算循环的更快方法。

result = sum(e.calculate_result(i).real for i in xrange(10000) for e in element_list) 

使用 reduce() 可能会使其更快,但我认为它不会更快。 reduce() 的最大节省是如果你可以避免一遍又一遍地绑定(bind)名称,但我们需要绑定(bind)名称 e 以便我们可以调用 e.calculate_result (i).real 即使 e 的类型可以是任何类型。

如果你能做这样的事情,它可能会更快一些。

import itertools as it 
import operator as op 
result = reduce(op.add, it.imap(SomeClass.calculate_something, it.product(element_list, xrange(10000)))) 

同样,主要的节省是避免绑定(bind)名称。 it.product() 返回包含 (e, i) 的元组,其中 e 是 element_list 中的一个元素,并且i 是来自 xrange(10000) 的数字。然后 it.imap() 将调用该函数并将元组作为参数传递。然后 reduce() 将对所有内容求和。实际上,仅调用 sum() 可能与 reduce(op.add) 一样好,但您可以两种方式都尝试一下,看看其中一种是否比另一种稍快.如果您能为 SomeClass.calculate_something 找出一些合理的东西,那么也许您可以完成这项工作。

嗯,可能值得尝试让 sum()(或 reduce())计算复数和,然后在和时丢弃虚部已经完成了。这会比每个值访问一次 .real 属性更快吗?我不确定,但它可能会帮助您使 reduce() 版本正常工作。

编辑:

您应该尝试在 PyPy 下运行您的程序。

http://pypy.org/

如果你这样做,一定要使用这一行而不是我展示的第一行:

result = sum(e.calculate_result(i).real for e in element_list for i in xrange(10000)) 

这样,您将每个元素 e 用于连续 10000 次调用,这应该有助于 PyPy 即时编译器(“JIT”)生成更好的代码。我不知道 JIT 是否只对 10000 次调用有帮助,但似乎应该尝试一下。