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

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

持续更新...

相关推荐
努力的ping17 小时前
qt信号和槽
开发语言·qt
AGANCUDA17 小时前
qt中vtk显示pcl的点云类
开发语言·qt
小马过河R17 小时前
tRPC-GO 框架Helloworld实践初体验
开发语言·分布式·后端·架构·golang·gin·beego
GoodStudyAndDayDayUp17 小时前
WIN11安装配置验证java\maven
java·开发语言·maven
fish_xk17 小时前
用c++写控制台贪吃蛇
开发语言·c++
一 乐17 小时前
游戏账号交易|基于Springboot+vue的游戏账号交易系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·游戏
王燕龙(大卫)17 小时前
rust:trait
开发语言·后端·rust
合作小小程序员小小店17 小时前
桌面开发,物业管理系统开发,基于C#,winform,mysql数据库
开发语言·数据库·sql·mysql·microsoft·c#
程序员-周李斌17 小时前
LinkedList 源码深度分析(基于 JDK 8)
java·开发语言·数据结构·list
西洼工作室17 小时前
前端自制设备模拟器模拟不同终端展示效果
前端·css3·js·响应式开发