将对象实例附加到列表中只能通过耗时的深拷贝完成,我该如何改变这种情况?

3
我有一个来自pymzml包的pymzml.run.Reader类。这是一个生成器对象,循环遍历它时会产生Spectrum类的实例(也来自pymzml包)。我正在将不同的实例进行比较。由于pymzml.run.Reader是一个生成器对象,在循环遍历之后它们就不能再使用了,因此我将它们保存在列表中以便以后进行比较。
然而,当我将它们保存在列表中,然后循环遍历该列表并打印出光谱的ID时,它只显示了最后一个光谱。为了澄清这一点:
import pymzml

def test(msrun):
    for spectrum in msrun:
        print spectrum['id']            
        spectrumList.append(spectrum)
    print '-'*20
    for i in spectrumList:
        print i['id']

msrun = pymzml.run.Reader(r'JG_Ti02-C1-1_C2-01A_file1.aligned.mzML')

提供:

1
2
3
4
5
--------------------
5
5 
5 
5
5

pymzml有一个deRef()函数,可以创建光谱的深度拷贝,因此以下代码可以正确执行:

import pymzml

def test(msrun):
    for spectrum in msrun: 
        print spectrum['id']
        spectrumList.append(spectrum.deRef())

msrun = pymzml.run.Reader(r'JG_Ti02-C1-1_C2-01A_file1.aligned.mzML') 

然而,制作深拷贝是我试图从我的应用程序中摆脱的主要瓶颈。我如何将频谱实例附加到列表中,使得不仅最后一个频谱被多次附加?

1个回答

1

不能只是保存最后一个频谱 -- 你正在做正确的事情将每个对象保存到列表中。

问题在于你一遍又一遍地获取相同的对象。

在循环中打印id(spectrum)以获取其内存地址,将显示它是一个重复的对象,其id和其他属性已更改。

虽然你不一定需要copy.deepcopy(),但确实需要制作副本。尝试使用copy.copy(),并查看Spectrum.decRef()源代码以了解它如何进行复制。

很可能,你需要decRef()每一个来使它们独立 -- 否则,为什么类会提供一个特殊的方法呢?


是的,你说得对,它们是相同的内存地址。Spectrum.deRef()使用深拷贝并剥离了一些信息,这需要很长时间...无论如何,感谢你的回答。 - Niek de Klein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接