2016-08-03 60 views
0

这是一个有点尴尬,但有一点困难的我有一个相当简单的(至少应该是)任务:将大型文件分成几个小的,随机写入多个文件

我想有一个脚本需要一个大文本文件(几个GB)并分成较小的部分。然而,这种分区应该不是按行的顺序发生的,而是基于匹配的字符串模式,因此每行/条目应该根据起始字符进行分类。因此,该算法看起来是这样的:

  1. 在字典定义类别{键:模式}
  2. 定义匹配/分类功能
  3. 打开输入文件,并开始重复条目
  4. 分类每个进入
  5. 写出来进入到相应的文件

我遇到的问题是与输出文件,具体如下:

  • 我是否提前申报?类别数量可能因实例而异,所以我在技术上不知道要打开多少个文件。另外,不能保证每个类别都在输入数据中表示,因此创建没有内容的文件是很愚蠢的。

    • 如果我遍历字典中的类别,并打开一堆文件;我如何跟踪哪个文件是哪个键?有另一个字典,即dict2 {key : file}感觉像矫枉过正,并不是特别漂亮的要么...

    • 如果我不提前打开文件,并打开/关闭一个新的io频道,每次我需要写入文件,我认为会有很大的开销。

与开口仅在需要时的文件的另一个复杂因素是以下;每次运行脚本时,我都想覆盖结果文件。但是如果我在主循环中有文件访问权限,我将需要打开文件以进行追加。

下面是测试代码,我到目前为止有:

from itertools import islice 
import random, sys, os 

cats = { 
    "key1" : "<some pattern>", 
    "key2" : "<some other pattern>", 
    "key3" : "<yet another pattern>"} 

def delta(x, s): 
    return sum([int(c0 != c1) for c0,c1 in zip(x,s)]) 

def categorize_str(x, cats): 
    d = {cat : delta(x,tag) for cat,tag in cats.items()} 
    return min(d, key=d.get) 

def main(): 
    file = sys.argv[1] 
    nseq = None if len(sys.argv) < 3 else int(sys.argv[2]) 

    path = os.path.dirname(file) 
    base = os.path.basename(file)) 
    (name,ext) = os.path.splitext(base) 
    for k in cats.keys(): # <---- 
     outfile = os.path.join(path, ''.join([name, "_", k, ext]) 
     # what do I do with outfile now??? 

    read = ... # library call to that opens input file and returns an iterator 
    for rec in islice(read,nseq): 
     c = categorize_str(rec, cats) 
     # depending on c, write to one of the "outfile"s 

if __name__ == "__main__": 
    main() 

回答

0

理念:定义一个名为,比如说类模式。在这里有几个成员变量:一个是你已经有的"<some pattern>";另一个是文件名;第三种是用于在该文件上下一次调用open()的模式。这个模式第一次是“w”(创建一个新文件),然后你的代码将把它改变为“w +”,所以你可以追加任何后来的写入。这个类的实例作为值进入“猫”字典。这解决了您反对使用多个字典的问题 - 您需要处理一个类别的所有信息都保存在一个对象中。它也允许你避免创建空文件。

也许操作系统将处理好几个文件做很多小的附加问题。如果这是一个性能瓶颈,那么您将需要做更多的工作(也许您可以在一次将它们写出之前在列表中缓存一些更新)。

相关问题