Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从磁盘读取列表是否比加载字典更好?_Python_List_Dictionary_Performance - Fatal编程技术网

Python 从磁盘读取列表是否比加载字典更好?

Python 从磁盘读取列表是否比加载字典更好?,python,list,dictionary,performance,Python,List,Dictionary,Performance,我正在构建一个应用程序,在这个应用程序中,我试图允许用户提交公司和日期对的列表,并找出当天是否有新闻事件。新闻事件以公司标识符和日期作为关键字存储在字典中 newsDict('identifier','MM/DD/YYYY')=[list of news events for that date] 这本字典原来比我想象的要大得多,太大了,甚至无法在内存中建立它,所以我把它分成三部分,每一部分仅限于特定范围的公司标识符 我的计划是获取用户提交的列表,并使用字典组获取公司标识符的用户列表,以匹配预

我正在构建一个应用程序,在这个应用程序中,我试图允许用户提交公司和日期对的列表,并找出当天是否有新闻事件。新闻事件以公司标识符和日期作为关键字存储在字典中

newsDict('identifier','MM/DD/YYYY')=[list of news events for that date]
这本字典原来比我想象的要大得多,太大了,甚至无法在内存中建立它,所以我把它分成三部分,每一部分仅限于特定范围的公司标识符

我的计划是获取用户提交的列表,并使用字典组获取公司标识符的用户列表,以匹配预期会找到公司事件的特定newsDict,然后逐个加载newsDict以获取值

现在我想知道是否最好将新闻事件保存在一个列表中,列表中的每一项都是一个元组和另一个列表的子列表

[('identifier','MM/DD/YYYY'),[list of news events for that date]]
我当时的想法是,我将拥有一本字典,其中包含每个公司标识符的列表范围

 companyDict['identifier']=(begofRangeinListforComp,endofRangeinListforComp)
我将使用用户输入查找所需的范围,并构建一个标识符列表和按范围排序的范围。然后,我只需阅读列表中适当的部分,以获取数据并构建输出

我看到这一点的最大原因是,即使将字典分成三部分,在我的机器上加载每个部分也需要大约两分钟,而字典最终需要大约600到750MB的ram

我惊讶地注意到,加载一个包含800万行的列表只需大约15秒,并且使用了字典中1/3的内存,而字典中只有1/3的条目

此外,由于我可以在处理列表时丢弃列表中的行,因此在处理用户列表时将释放内存

我很惊讶,因为我认为字典是最有效的方法。但我的研究表明,字典比列表需要更多的内存。我对SO和其他地方的其他文章的阅读表明,任何其他结构都需要比列表指针更昂贵的指针分配。我是不是遗漏了什么?有没有更好的方法

在阅读了Alberto对我的评论的回答和回复后,我花了一些时间试图弄清楚如果我要使用db,该如何编写函数。现在,我可能会被困在这里,因为我不太懂db编程,但是

我认为使用db实现的代码要比以下代码复杂得多:

outList=[]
massiveFile=open('theFile','r')
for identifier in sortedUserList
# I get the list and sort it by the key of the dictionary 
    identifierList=massiveFile[theDict[identifier]['beginPosit']:theDict[identifier]['endPosit']+1]
    for item in identifierList:
        if item.startswith(manipulation of the identifier)
        outList.append(item)
我必须把它包装在一个函数中,如果我把列表转换成db,我看不到有什么比这更简单的了


当然,这并不是我参加这个论坛的原因。我仍然不认为使用另一种结构会节省内存。我有30000个公司标识符和大约3600个日期。我列表中的每一项都是一个OOD术语中的对象。这正是我努力的方向。在我放弃之前,我今天早上花了六个小时为一本词典整理数据。花那么多的时间来实现一个数据库,然后发现我使用了别人的半个gig或更多内存来加载它似乎有问题

对于如此大量的数据,您应该使用一个数据库。这比查看列表要好得多,而且是存储数据的最合适的方式。如果您使用的是Python,我相信它内置了SQLite。

字典将占用更多内存,因为它实际上是一个散列

您不必使用数据库,因为查找需求非常简单。只需使用文件系统

根据公司名称(或股票代码)创建目录结构,每个日期都有子目录。要查找数据是否存在并加载它,只需填写数据所在子目录的名称,然后查看它是否存在

例如,5月21日的IBM新闻将以C:\db\IBM\20090521\news.txt的形式发布,如果当天确实有新闻的话。您只需检查文件是否存在;没有搜索


如果您想尝试从那里提高速度,可以提出一个方案来缓存可能频繁请求的有限数量的结果(假设您正在操作服务器)。为此,您可以使用散列。

使用数据库的好处是什么?基本上,通过进行不同的SQL调用,您正在编码的所有功能都已经存在,因此您可以仅根据数据库中的表创建所需的所有不同类型的列表。数据库也不会将其携带的数据存储到RAM中,这是一个巨大的优势。Sqlite是python中的标准模块,我建议使用Elixir(SQLAlchemy)和表/查询管理器。聪明+1,但我不想添加复杂的目录结构,300K标识符将使它们很难遍历其目录结构。当然不希望在一个目录中包含数千个标识符。因此,您可以细分并创建C:\db\I\B\M\2009\05\21\news.txt,这比使用sqlite更简单,真的吗?有什么困难?symbol,datestr=“IBM”,“20090521”newsname=“C:/db/%s/%s/news.txt”%(“/”。如果(os.path.isfile(newsname)),则加入(symbol),datestr:。。。