【问题标题】:Renumbering a Sequence of Numbers With Gaps using Python使用 Python 对带有间隙的数字序列重新编号
【发布时间】:2020-12-16 16:17:01
【问题描述】:

我正试图弄清楚如何重新编号某种文件格式并努力使其正确。

首先,了解一些背景知识可能会有所帮助:计算化学中使用某种文件格式来描述扩展名为 .xyz 的分子的结构。第一列是用于识别特定原子(碳、氢等)的编号,随后的列显示它连接到的其他原子编号。下面是这个文件的一个小样本,但通常的文件要大得多。

  259   252             
  260   254                  
  261   255                  
  262   256                  
  264   248   265   268      
  265   264   266   269   270
  266   265   267   282      
  267   266                  
  268   264                  
  269   265       
  270   265   271   276   277
  271   270   272   273      
  272   271   274   278      
  273   271   275   279      
  274   272   275   280      
  275   273   274   281      
  276   270                  
  277   270                  
  278   272                  
  279   273                  
  280   274                  
  282   266   283   286      
  283   282   284   287   288
  284   283   285   289      
  285   284                  
  286   282                  
  287   283                  
  288   283                  
  289   284   290   293      
  290   289   291   294   295
  291   290   292   304

如您所见,数字 263 和 281 不见了。当然,可能还有更多缺失的数字,所以我需要我的脚本来解决这个问题。下面是我到目前为止的代码,并且还给出了missing_nums 和missing_nums2 列表,但是,我通常会从脚本的早期部分获取它们。列表 missing_nums2 的最后一个元素是我想要完成编号的地方,因此在本例中:289。

    missing_nums = ['263', '281']
    missing_nums2 = ['281', '289']

    with open("atom_nums.xyz", "r") as f2:  
            lines = f2.read()
    
    for i in range(0, len(missing_nums) - 1):
        if i == 0:
            with open("atom_nums_out.xyz", "w") as f2: 
                
                replacement = int(missing_nums[i])
                
                for number in range(int(missing_nums[i]) + 1, int(missing_nums2[i])):
                    lines = lines.replace(str(number), str(replacement))
                    replacement += 1
                
                f2.write(lines)
    
        else:
            with open("atom_nums_out.xyz", "r") as f2:  
                lines = f2.read()
                
            with open("atom_nums_out.xyz", "w") as f2:   
                
                replacement = int(missing_nums[i]) - (i + 1)
                print(replacement)
                
                for number in range(int(missing_nums[i]), int(missing_nums2[i])):
                    lines = lines.replace(str(number), str(replacement))
                    replacement += 1
                    
                f2.write(lines)

问题在于随着文件变大,数字似乎会重复,原因我无法弄清楚。我希望有人可以在这里帮助我。

编辑:使用上述示例的代码的所需输出将是

  259   252                  
  260   254                  
  261   255                  
  262   256                  
  263   248   264   267      
  264   263   265   268   269
  265   264   266   280      
  266   265                  
  267   263                  
  268   264                  
  269   264   270   275   276
  270   269   271   272      
  271   270   273   277      
  272   270   274   278      
  273   271   274   279      
  274   272   273   279      
  275   269                  
  276   269                  
  277   271                  
  278   272                  
  279   273                  
  280   265   281   284      
  281   280   282   285   286
  282   281   283   287      
  283   282                  
  284   280                  
  285   281                  
  286   281                  
  287   282   288   291      
  288   287   289   292   293
  289   288   290   302

这确实是我作为这个小样本的输出得到的,但随着缺失数字的增加,它似乎不起作用,并且我得到了重复的数字。如果有人愿意,我可以提供整个文件。

谢谢!

【问题讨论】:

  • 您的意思是数字在输入文件中重复还是只是在输出文件中重复?
  • 如果您正在使用 IDE现在是学习其调试功能或内置 Python debugger 的好时机。在程序中的关键点打印 stuff 可以帮助您跟踪正在发生或未发生的事情。 What is a debugger and how can it help me diagnose problems?
  • 你为什么使用with open("atom_nums.xyz", "r") as f2with open("atom_nums_out.xyz", "w") as f2?应该一个用f1,另一个用f2吗?
  • 您的预期结果是什么?可以举个例子吗?
  • @wwii 感谢您的回复,很抱歉我没有说清楚。我现在已将预期输出添加到 OP。

标签: python python-3.x file chemistry


【解决方案1】:

假设我对missing_nums 和missing_nums2 列表的解释是正确的,这就是我执行操作的方式。

from os import rename
def fixFile(fn, mn1, mn2):
        with open(fn, "r") as fin:
            with open('tmp.txt', "w") as fout:
                for line in fin:
                    for i in range(len(mn1)):
                        minN = int(mn1[1])
                        maxN = int(mn2[i])
                        for nxtn in range(minN, maxN):
                            line.replace(str(nxtn), str(nxtn +1))
                    fout.write(line)
        rename(temp, fn)        
            

missing_nums = ['263', '281']
missing_nums2 = ['281', '289']
fn = "atom_nums_out.xyz"

fixFile(fn, missing_nums, missing_nums2)

注意,我一次只读取一次文件,一次将结果写出一行。在处理完所有数据后,我将临时文件重命名为原始文件名。这意味着,更长的文件不会占用内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    相关资源
    最近更新 更多