这有点令人尴尬,但我对一个相当简单(至少应该是)的任务有点困难:
我希望有一个脚本可以获取一个大文本文件(几个GB)并分成更小的部分。然而,该分区应该不是按照行的顺序发生,而是基于匹配的字符串模式,这样每个行/条目应该基于起始字符进行分类。所以算法看起来像这样:
我遇到的问题是输出文件,特别是:
我是否提前申报?类别的数量可能会因实例而异,因此我在技术上不知道要打开多少个文件。此外,无法保证每个类别都在输入数据中表示,因此创建没有内容的文件会很愚蠢。
如果我遍历dict中的类别,并打开一堆文件;如何跟踪哪个文件的哪个键?有另一个字典,即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 :(得分:0)
想法:定义一个名为Pattern的类。这里有几个成员变量:一个是你已经拥有的"<some pattern>"
;另一个是文件名;第三种是用于下一次调用该文件的open()的模式。该模式将是第一次“w”(创建一个新文件),然后您的代码将更改为“w +”,因此您将附加任何后续写入。这个类的实例作为值进入“cats”字典。这解决了您对使用多个字典的异议 - 处理一个类别所需的所有信息都保存在一个对象中。它还允许您避免创建空文件。
也许操作系统可以很好地解决对几个文件进行大量小附加的问题。如果这是性能瓶颈,那么您还需要做更多的工作(也许您可以在一步完成之前将一些更新缓存在列表中)。