Python文件编码读取和处理整理知识点

最近作业要做文本压缩,要用到不少相关的代码,刚好自己这一块不怎么熟,可能以后也会用到,所以总结一番。

读取文件

python 复制代码
    with open(file_path, 'r', encoding='utf-8') as f:
        text = f.read()

这意味着:以只读模式 r 打开这个路径对应的文件,按照 UTF-8 编码解码成 Python 字符串。

一般会加with:with ... as f::用上下文管理器保证用完会自动关文件。

如果我们不选择with ... as,当然也有以下的等价写法,但是就会需要手动关闭,否则文件会一直占用内存。

python 复制代码
f = open(file_path, 'r', encoding='utf-8')
text = f.read()
f.close()    

去除所有空白字符

python 复制代码
visible_chars = [ch for ch in text if not ch.isspace()]  

ch.isspace()就是检测这个字符是不是换行,空格等等

Python中创建字典以统计字母数量

python 复制代码
    freq = {}
    for ch in visible_chars:
        freq[ch] = freq.get(ch, 0) + 1

在python中不需要像C++那样使用std::map<char, int> 来创建字典,只需要:freq = {},就会默认创建新的空字典。

类比来说:

  • []是创建新列表,类似于C++的std:vector
  • ()是创建新元组,对应的是C++的std::tuple

在这里,实际上还有一个逻辑需要留意,在C++中,我们如果创建一个map,并且指定某个key,如果该key不存在,C++会自动创建一个新的key。

例如

cpp 复制代码
freq['a']++;

如果'a'不存在,C++会自动创建一个新的key,且设置默认值为0。

这一点与python的dict不同,python如果面对不存在的key,会抛出keyerror

bash 复制代码
    freq[ch]+=1
KeyError: '\ufeff'

因此一般会用:

python 复制代码
freq[ch] = freq.get(ch, 0) + 1 #dict.get(key, default)

来面对这种情况,后面的数字为默认值,实际上就是类似于打印C++里的freq['c']

读取编码表

试想我们已经得到了一个symbol和code的对应表格,我们怎么样逐行字符处理获得symbol和code呢?

例如这个txt可能如下:

bash 复制代码
0: 1100000110111110
1: 110000011010001
2: 1100000110110001
3: 11000001101111010

我们可以用比较优雅的方式读取:

python 复制代码
        for line in f:
            if ':' not in line:
                continue
            sym, code = line.strip().split(':')

这里的line.strip()是必要的,因为他会把读取字符串两侧的制表符,空格和换行符都删除。

python的line in f实际上是不断调用readline() 会一直读取字符,直到遇到 \n(换行符)或文件末尾 EOF;然后返回包含那一整行的字符串(包括末尾的 \n)。

sym, code = line.strip().split(':')是一个序列解包 过程,它自动将列表的第一个元素赋给sym,第二个元素赋给 code。实际上这样不稳健,如果我们的encode代码会写入两个冒号就会使得报错(因为此时每一行被分为了大于两份)。

我们可以使用sym, code = line.strip().split(':', 1) 来只按照第一个冒号区分。

python中读取系统参数列表

假设我们需求在运行脚本时就同时传入,码字对应表,编码文件和输出文件。例如:

bash 复制代码
python XXX.py <code-file-path> <source-file-path> <output-file-path>

Python 会自动把命令行里的这些"空格分开的字符串"放进 sys.argv,一般我们不需要程序名字本身,所以会用sys.argv[1:]来读取后面的几个。根据数量我们就可以提前抛出错误了。

python 复制代码
 if len(sys.argv) != 5:
        print("You should enter format like: python XXX.py <method> <op> <input> <output>")
        sys.exit(1)

对源文件进行Encode

python 复制代码
bits = ''
for ch in text:
    if ch in code_map:
        bits += code_map[ch]

简约的字典赋值版本为:

python 复制代码
bits = ''.join(code_map[ch] for ch in text if ch in code_map)

可以理解为:

  • 逐个取出原文中的字符 ch

  • 查找 code_map[ch] 得到对应的二进制编码

  • 把这些二进制字符串拼接起来

持续更新...

相关推荐
·心猿意码·2 小时前
C# 垃圾回收机制深度解析
开发语言·c#
IT_陈寒2 小时前
WeaveFox 全栈创作体验:从想法到完整应用的零距离
前端·后端·程序员
程序员爱钓鱼2 小时前
Python编程实战 - Python实用工具与库 - 正则表达式匹配(re 模块)
后端·python·面试
程序员爱钓鱼2 小时前
Python编程实战 - Python实用工具与库 - 爬取并存储网页数据
后端·python·面试
pixle02 小时前
从零学习Node.js框架Koa 【一】 Koa 初探从环境搭建到第一个应用程序
前端·node.js·web·koa.js·web全栈·node服务端框架
抹茶生活2 小时前
CSS浮动样式
前端·css
bin91532 小时前
PHP文档保卫战:AI自动生成下的创意守护与反制指南
开发语言·人工智能·php·工具·ai工具
匀泪2 小时前
CE(Linux的例行性工作)
前端·chrome
歪歪1002 小时前
解决多 Linux 客户端向 Windows 服务端的文件上传、持久化与生命周期管理问题
linux·运维·服务器·开发语言·前端·数据库·windows