跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • open()读取文件问题(假设思考题).
未分類
16 1 月 2021

open()读取文件问题(假设思考题).

open()读取文件问题(假设思考题).

資深大佬 : zyb201314 0

1, in.txt 文本文件非常非常大,(意为着不能一次读取到内存中).
2, in.txt 文件没有换行,都在一行内,意为着直接使用 readlines 无效.
3, in.txt 里内都是英文及标点符. 需要统计英文词频到 output.txt 文件.

问: 下面通过迭代器 iter()函数封装的代码,能否解决,上面内容不足问题? 如不能,该如何处理?若可以, 该如何验证,内存使用量. 请大佬指教,谢谢!!
代码如下:

from collections import defaultdict
import re

a=iter(re.split(‘[^w]+’,open(“in.txt”,”r”).read()))
#此条是否可避免使用内存过大?

d=defaultdict(int)
for b in a:
d[b]+=1

out=dict(sorted(d.items(),key=lambda x:x[1],reverse=True))

f=open(“output.txt”,”w”)
f.write(repr(out))
f.close()

大佬有話說 (10)

  • 資深大佬 : ysc3839

    不能,因为 f.read() 就会把整个文件读到内存。

  • 資深大佬 : fuis

    我看到 split 和 read 就不看了

  • 主 資深大佬 : zyb201314

    @ysc3839 谢回复

  • 資深大佬 : liprais

    mmap 完事

  • 資深大佬 : xpresslink

    建议分块读。
    FILE_PATH = “/path/to/your/in.txt”
    CHUNK_SIZE=1024*1024*64 #64M 块
    def read_in_chunks(filePath, chunk_size):
    □□□□file_object = open(filePath,’r’,encoding=’utf-8′)
    □□□□while True:
    □□□□□□□□chunk_data = file_object.read(chunk_size)
    □□□□□□□□if not chunk_data:
    □□□□□□□□□□□□break
    □□□□□□□□yield chunk_data

    for chunk in read_in_chunks(FILE_PATH, CHUNK_SIZE):
    □□□□handling_func(chunk)

    有很少部分单词被块截断,如果要求非常高精确,自己再处理一下。

  • 資深大佬 : neoblackcap

    自己写一个简单 parser 不就可以了?实际上内存使用量可以是一个最大单词长度的两倍(动态扩展)
    这个问题不是跟处理 TCP 流一样吗?
    你只要读一定量的数据进你分配的缓冲区(预分配),然后开始解析。
    1.如果整个缓冲区都读完了但是还是未能解析出一个单词( token )那么就将缓冲区变为已有的两倍,继续读取内容并重复此步骤。
    2.如果解析到缓冲区末端,但是不是结束符(我假定是空格符),那么就继续读取你缓冲区长度减去未解析字符长度的字符。
    然后继续上面的流程,进行解析。但是有直到读到文件底部就可以了。

  • 資深大佬 : autoxbc

    考虑一下换语言? ry 大神新作 Deno,有个现成的函数直接对应你的需求

    https://deno.land/[email protected]/io#readstringdelim
    ———-
    readStringDelim

    Read reader[like file] chunk by chunk, splitting based on delimiter.

    import { readStringDelim } from “https://deno.land/[email protected]/io/mod.ts”;
    import * as path from “https://deno.land/[email protected]/path/mod.ts”;

    const filename = path.join(Deno.cwd(), “std/io/README.md”);
    let fileReader = await Deno.open(filename);

    for await (let line of readStringDelim(fileReader, “n”)) {
    console.log(line);
    }

    Output:

    # std/io

    ## readLines

    “`ts
    import * as path from “https://deno.land/[email protected]/path/mod.ts”;

    ## Rest of the file

  • 主 資深大佬 : zyb201314

    先谢过各大佬!

    @liprais
    稍后去了解.

    @autoxbc
    Python 学了近半年,算是新人吧,还没有精力了解别的语言哟~
    @neoblackcap

    学习了. 本人很菜,不知理解对不对.关于第 2 点,解析到缓冲区末端,如果不是符号,是否大概率英文词分两截?

    @xpresslink
    辛苦! 我想这种处理方案,应该是比较优解和大众吧.

  • 資深大佬 : Latin

    with open(‘filename’) as file:
    for line in file:
    do_things(line)

    不换行也试试这个

  • 資深大佬 : neoblackcap

    @zyb201314 有两种可能,一种是一个单词很长,你还没读完(截断了),第二种是你有可能读到单词最末尾的字符(刚刚好),两种情况都需要再读数据再解析

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具