如何在不将字典加载到内存中的情况下写入 Python 字典?

How to write to Python dictionary without loading the dictionary into memory?

提问人:O.rka 提问时间:11/14/2023 更新时间:11/14/2023 访问量:57

问:

我有一个大表,我想将其转换为 Python 字典,但我不想将所有数据加载到内存中。

是否可以在不先构建对象的情况下主动写入 pickle 转储?

例如:

import gzip
f_out = open("output.dict.pkl.gz", "wb")

with open("table.tsv", "r") as f_in:
    for line in f_in:
        line = line.strip()
        if line:
            fields = line.split("\t")
            k = fields[3]
            v = fields[1]

            # Pseudocode
            f_out[k] = v # I know this won't work but just so you can see my goal

# Close the pickle file
f_out.close()
python 字典 bigdata pickle 大数据

评论


答:

1赞 ShadowRanger 11/14/2023 #1

由于键是字符串,因此可以使用该模块创建由极简数据库支持的类似 -的对象,其中键是字符串,值是单独腌制的值。您还应该使用该模块来正确解析 TSV 数据:shelvedictcsv

import csv
import shelve

with open("table.tsv", newline="") as f_in, shelve.open("output.db") as shelf:
    for row in csv.reader(f_in, delimiter='\t'):
        if row:
            k = row[3]
            v = row[1]
            shelf[k] = v

重要的是,这意味着当您稍后加载它以读取少数密钥时,您也不需要将整个内容加载到内存中。

评论

0赞 Pedro Lobito 11/14/2023
Shelve 是一个不错的选择,但值在访问时会加载到内存中,因此,如果值非常大,检索它可能会消耗大量内存。
1赞 ShadowRanger 11/14/2023
@PedroLobito:是的。但只要你在打开货架时不使用,它就不会被缓存在货架本身上;你使用的内存将取决于你访问的你保留的内容的数量(保存到变量或其他内存中的数据结构)。如果确实使用 ,则在缓存开始增长过大时,需要手动调用 to 来清除缓存。writeback=Truewriteback=True.sync()
0赞 O.rka 11/14/2023
有趣的是,这功能类似于泡菜对象,但被称为架子?
2赞 ShadowRanger 11/14/2023
@O.rka:它的作用类似于 ,但每次分配给键时,它都会腌制值,并将键和值存储到磁盘上的底层数据库中。因此,它是按值计算的泡菜,而不是一个大泡菜,这就是实现较低内存(但可能较高磁盘)消耗的方式。dict