首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由多个过滤生成器消耗单个生成器

由多个过滤生成器消耗单个生成器
EN

Stack Overflow用户
提问于 2017-06-07 15:21:37
回答 1查看 32关注 0票数 0

我有一个包含如下记录的文件:

代码语言:javascript
复制
>uniqueid#BARCODE1
content content
content content
>uniqueid#BARCODE2
content content
content content
>uniqueid#BARCODE1
content content
content content
...

有1000万条记录,其中有300个唯一条形码,条码的顺序是随机的。我的目标是将文件分成300个文件。我只想用生成记录的生成器执行一次文件传递。

过去,我通过多次读取文件,或者将整个文件加载到内存中,解决了这个问题。我想使用生成器方法来解决这个问题,以减少内存的使用,并且只读取文件一次。

是否可以实例化300个生成器,并有一些逻辑将记录分派给正确的生成器?,然后我可以简单地将每个生成器的内容写成一个文件。我是否需要将句柄打开到我想要同时写入的所有300个文件?

EN

回答 1

Stack Overflow用户

发布于 2017-06-07 16:11:52

是的,可以用发电机来完成,但我们不需要300台,只要1台就够了。

据我所知,'uniqueid#BARCODE1'条形码由两部分组成:

  • '>uniqueid#'前缀
  • 'BARCODE1'条形码本身。

所以让我们从编写简单的检查程序开始

代码语言:javascript
复制
BAR_CODE_PREFIX = '>uniqueid#'


def is_bar_code(text):
    return text.startswith(BAR_CODE_PREFIX)

然后,为了解析条形码内容,我们可以编写生成器。

代码语言:javascript
复制
def parse_content(lines):
    lines_iterator = iter(lines)
    # we assume that the first line is a barcode
    bar_code = next(lines_iterator)
    contents = []
    for line in lines_iterator:
        if is_bar_code(line):
            # next barcode is found
            yield bar_code, contents
            bar_code = line
            contents = []
        else:
            contents.append(line)
    # to yield last barcode with its contents
    yield bar_code, contents

那么假设您想以条形码命名文件,我们可以编写。

代码语言:javascript
复制
def split_src(src_path):
    with open(src_path) as src_file:
        for bar_code, content_lines in parse_content(src_file):
            bar_code_index = bar_code[len(BAR_CODE_PREFIX):].rstrip('\n')
            # we use `append` mode
            # because in the different parts of file 
            # there are contents of the same barcode
            with open(bar_code_index, mode='a') as dst_file:
                dst_file.writelines(content_lines)

在整个文件中只走一遍。

测试

让我们创建由以下内容组成的src.txt文件

代码语言:javascript
复制
>uniqueid#BARCODE1
content11
>uniqueid#BARCODE2
content21
>uniqueid#BARCODE1
content12
content12
>uniqueid#BARCODE3
content31
>uniqueid#BARCODE2
content22

然后在打电话之后

代码语言:javascript
复制
split_src('src.txt')

下一个文件将被创建:

  • 带线的BARCODE1 content11 content12 content12
  • 带线的BARCODE2 content21 content22
  • 带线的BARCODE3 content31
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44416771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档