You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中使用ProDy生成PDB文件时,列表最后一项覆盖所有文件内容的问题

Python中使用ProDy生成PDB文件时,列表最后一项覆盖所有文件内容的问题

嘿,我一眼就瞅出你代码里的问题啦——嵌套循环的逻辑完全错了,导致每个PDB文件被所有pocket的内容反复写入,最后一次写入的自然是最后一个pocket的内容,所以所有文件都被它覆盖了。

先给你上能直接解决问题的代码,两种写法任你选:

写法1:边处理边写入(更省内存)

不用先把所有内容存到列表里,处理一个PDB ID就直接生成对应的口袋文件,逻辑最清晰:

ids = ['1b7f', '3wbm']

for pdb_id in ids:
    # 解析PDB文件
    p = parsePDB(pdb_id)
    # 筛选口袋区域
    pocket = p.select('within 4.5 of protein and nucleic')
    # 生成对应文件名
    filename = f"{pdb_id}_pocket.pdb"
    # 直接写入
    writePDB(filename, pocket)

写法2:先收集再配对写入(适合需要复用pockets的场景)

如果确实需要先把所有pockets和文件名都存起来,那一定要用zip把两个列表一一对应,而不是嵌套遍历所有组合:

ids = ['1b7f', '3wbm']
pockets = []
names = []

# 先收集所有口袋和对应的文件名
for i in ids:
    p = parsePDB(i)
    pocket = p.select('within 4.5 of protein and nucleic')
    pockets.append(pocket)
    names.append(f"{i}_pocket.pdb")

# 一对一配对写入,每个文件名对应唯一的pocket
for name, pock in zip(names, pockets):
    writePDB(name, pock)

为啥你的原代码会出问题?

你原来的代码里,在生成names的循环中又嵌套了两层循环:

for n in ids:
    name = n + '_pocket.pdb'
    names.append(name)
    for a in names:
        for pock in pockets:
            writePDB(a, pock)

这会导致:

  • 每新增一个文件名,就会把所有已存在的文件名,用所有的pocket各写一遍
  • 比如生成第二个文件名3wbm_pocket.pdb时,会先把1b7f_pocket.pdb用第一个pocket写一遍,再用第二个pocket写一遍(直接覆盖),接着对3wbm_pocket.pdb做同样操作,最后所有文件自然都是最后一个pocket的内容

至于你想尝试的map函数,其实也能实现,但需要用lambda包装参数,比如:

from functools import partial

# 先把每个文件名和对应的pocket绑定
for name in names:
    # 固定文件名,生成只接受pocket的函数
    bound_write = partial(writePDB, name)
    # 不过这里还是要注意一一对应,不能直接遍历所有pockets
    # 所以其实还是zip配对更直观

但说实话,这种写法可读性不如直接用zip循环,没必要舍近求远~

火山引擎 最新活动