无法在内存中存储大量字符串

时间:2014-09-23 21:41:49

标签: python regex linux python-2.7

我的数据如下:

#@ De
A B C.
#@ dabc
xyz def ghi.
#@ <MyName_1>
Here is example.
#@ Df
A B C.
#@ <MyName_2>
De another one.
#@ <MyName_3>
Df next one.
#@ dabc1
xyz def ghi.
#@ <MyName_4>
dabc this one.

将其转换为以下形式:

A B#1 C. //step 1 -- 1 assigned to the first occurrence of A B C.
xyz def#1 ghi. //1 assigned to first occurrence of xyz def ghi
Here is example
A B#2 C. //step 1 -- 2 assigned in increasing order
B#1 another one. //step 2
B#2 next one.
xyz def ghi.
def#1 this one.

//这里代表评论而不是输出的一部分。

算法如下。

  1. 如果#@后面的第二行重复出现。然后,追加到 中间字#号,其中number是数字标识符,是 按重复的第二行递增顺序分配。
  2. 用#字号替换#@ ...,无论何时发生。
  3. 删除所有#@,其中第二行没有重复。
  4. 为了达到这个目的,我将存储所有三元组,然后查找它们的出现次数,以便按递增顺序分配数字。是否有其他方法可以在python中实现相同的功能。实际上我的文件是500GB,并且无法将所有三元组存储在内存中以便查找它们的出现次数。

1 个答案:

答案 0 :(得分:1)

如果您需要的东西就像一个字典,但是太大而无法保存在内存中,那么您需要的是一个键值数据库。

最简单的方法是使用dbm类型的库,它是一个非常简单的键值数据库,与dict的接口几乎完全相同,只是它只允许字符串对于键和值,并有一些额外的方法来控制持久性和缓存等。根据您的平台以及Python 2.7的构建方式,您可以使用以下任何一种方法:

如果您的Python安装不包含它们,那么最后三个都可以在PyPI上使用,只要您拥有相应版本的libbsddb本身且其许可证没有任何问题。

问题在于,根据您的平台,可能不存在各种底层数据库库(当然您可以下载C库,安装它,然后构建并安装Python包装器),或者可能不支持数据库大,或者可能这样做,但只是以极其低效的方式(或者,在少数情况下,以有缺陷的方式......)。

希望其中一个能为你效劳,但你真正知道的唯一方法就是测试你拥有的所有东西。

当然,如果我理解正确,你将字符串映射到整数,而不是字符串。您可以使用shelve模块,它包含任何dbm类似的库,允许您使用字符串键,但任何可选择的值作为值......但对于类似的情况,这可能是一个巨大的过度杀戮(可能会扼杀您的表现)这个;你只需要改变这样的代码:

counts.setdefault(key, 0)
counts[key] += 1

......进入这个:

counts.setdefault(key, '0')
counts[key] = str(int(counts[key]) + 1)

当然,您可以轻松编写一个为您执行此操作的包装类(甚至可以支持Counter接口而不是dict接口)。


如果这不起作用,则需要更强大的数据库。

大多数Python版本都在stdlib中附带sqlite3,但使用它需要学习一个非常低级的API,并学习SQL,这是一种完全不同的语言,与Python非常不同。 (那里还有各种不同的关系数据库,但你不应该需要它们。)

还有各种各样的查询表达式库,甚至是完整的对象关系映射器,比如SQLAlchemy(可以使用哪种方式),让你以更加Pythonic的方式编写查询,但它仍然是不会像使用dictdbm那么简单。 (话虽如此,围绕dbm包裹类似SQLAlchemy的界面并不难。)

还有各种各样的非关系型或半关系型数据库,这些数据库通常归入NoSQL项,其中最简单的基本上是类固醇dbm。同样,他们通常需要学习一个非常低级的API,有时候也需要一个查询语言 - 但是其中一些将拥有很好的Python库,使它们更容易使用。