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] 得到对应的二进制编码

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

持续更新...

相关推荐
阿虎儿29 分钟前
React Context 详解:从入门到性能优化
前端·vue.js·react.js
Ray Liang1 小时前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
Sailing1 小时前
🚀 别再乱写 16px 了!CSS 单位体系已经进入“计算时代”,真正的响应式布局
前端·css·面试
AI攻城狮1 小时前
如何给 AI Agent 做"断舍离":OpenClaw Session 自动清理实践
python
喝水的长颈鹿1 小时前
【大白话前端 03】Web 标准与最佳实践
前端
千寻girling1 小时前
一份不可多得的 《 Python 》语言教程
人工智能·后端·python
爱泡脚的鸡腿1 小时前
Node.js 拓展
前端·后端
左夕2 小时前
分不清apply,bind,call?看这篇文章就够了
前端·javascript
Zha0Zhun3 小时前
一个使用ViewBinding封装的Dialog
前端
兆子龙3 小时前
从微信小程序 data-id 到 React 列表性能优化:少用闭包,多用 data-*
前端