如何在python中存储(和访问)非常大的列表

2024-10-01 17:23:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个超过400万行的文件,我想逐行读取,并对数据的第一个“列”执行操作。可能有重复的数据,我想确保我只执行这些操作一次,并且能够重新启动程序并从它停止的地方启动。在

我的解决方案是解析该行,将值存储到一个列表中,然后“If x not in list”执行操作,然后将该列表存储为pickle,如果/当程序终止/停止/被终止。在

但是这个脚本在运行了几个小时后出现故障,我想这是因为我在checkedFile列表中存储了大量MD5和而烧掉了所有的ram。在

因为这个文件太大了(4百万+个条目),我需要一些快速查找的东西,希望有一个简单的解决方案。谢谢!在

数据如下所示:6e5f6c90e6bf31c31283afb8dca93da8|鼠标.gif|10102017号

我当前的代码如下:

checkedFile = []

def readline(inFile):
print("Opening file: %s\n" % inFile)
try:
    with open(inFile, "r") as inputFile:
        for line in inputFile: # read in file line by line
            fileHash, garbage = line.split("|",1) 
            if fileHash not in checkedFile:
                checkedFile.append(fileHash)
                checkit(fileHash) # 

Tags: 文件数据in程序列表地方linenot
1条回答
网友
1楼 · 发布于 2024-10-01 17:23:00

我认为您面临的问题之一是您选择的数据结构。由于checkedFile是一个列表,因此检查列表中是否有一个散列O(N)time complexity。我的第一个建议是使用python set。这使用了一个性能为O(1)的哈希映射。在

checkedFile = set()

def readline(inFile):
    print("Opening file: %s\n" % inFile)
    with open(inFile, "r") as inputFile:
        for line in inputFile: # read in file line by line
            fileHash, garbage = line.split("|",1) 
            if fileHash not in checkedFile:
                checkedFile.add(fileHash)
                checkit(fileHash)

Python只对2 reasons进行真正的分段,所以内存肯定用完了。我觉得奇怪的是,你用列表存储出错了,因为每个哈希值是16字节×400万=64Mb,我想这与你典型的计算机上的内存量是不一样的。在

走持久化存储路线,我建议使用sqlite。此方法不会耗尽内存,因为它将存储在硬盘上。在

^{pr2}$

另外,您还可以缓存来自checkit的结果,以便在计算因某种原因停止时继续计算。这也有利于您,因为一个web请求需要最少的响应时间10ms。您提到web请求返回一个json响应。在sqlite with python如何在sqlite中存储json之前,我已经写过这方面的文章。您需要修改函数checkit以返回json数据。在

import sqlite3
import json

def adapt_json(data):
    return (json.dumps(data, sort_keys=True)).encode()

def convert_json(blob):
    return json.loads(blob.decode())

sqlite3.register_adapter(dict, adapt_json)
sqlite3.register_converter('JSON', convert_json)

connection = sqlite3.connect('cache.db', detect_types=sqlite3.PARSE_DECLTYPES)
CREATE_CACHE_TABLE = '''CREATE TABLE IF NOT EXISTS cache (
                         hash TEXT PRIMARY KEY,
                         check_results JSON
               )'''
SELECT_STATEMENT = 'SELECT hash FROM cache WHERE hash = ?'
INSERT_STATEMENT = 'INSERT INTO cache VALUES ?, ?'

with connection:
    connection.execute(CREATE_CACHE_TABLE)
with open(inFile, "r") as inputFile:
    for line in inputFile:
        fileHash, garbage = line.split("|", 1)
        with connection:
            if not connection.execute(SELECT_STATMENT, (fileHash,)).fetchone():
                json_data = checkit(fileHash)
                connection.execute(INSERT_STATEMENT, (fileHash, json_data))

如果你用最后的方法。你可以用不同的文件块并行运行这个程序,它仍然可以工作。此外,如果您最终得到一个更大的文件,这种方法应该可以很好地扩展。在

相关问题 更多 >

    热门问题