我正在编写一些需要存储和访问不同类型元素列表的 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 下运行您的程序。
如果你这样做,一定要使用这一行而不是我展示的第一行:
result = sum(e.calculate_result(i).real for e in element_list for i in xrange(10000))
这样,您将每个元素 e 用于连续 10000 次调用,这应该有助于 PyPy 即时编译器(“JIT”)生成更好的代码。我不知道 JIT 是否只对 10000 次调用有帮助,但似乎应该尝试一下。
