【问题标题】:How to sort a LARGE dictionary如何对大字典进行排序
【发布时间】:2016-03-26 08:40:21
【问题描述】:

我有一个处理大型 (~14gb) 文本文件的 python 脚本。我最终得到了一个键和值字典,但是当我尝试按值对字典进行排序时出现内存错误。

我知道字典太大而无法加载到内存中然后排序,但我该如何完成呢?

【问题讨论】:

  • 你用的是哪个版本的python?
  • 我不确定这会证明多大用处,但请查看此链接:stackoverflow.com/questions/14262433/… .. 你可以使用 pandas 来达到你的目的吗?
  • @amirouche python 2.7
  • 使用像内置sqlite3这样的数据库怎么样?即使是最简单的数据库也能轻松应对 14G 的数据,而您将不得不重新发明轮子...
  • 你可以使用mongodb这样的nosql数据库,这样可以省去你定义数据库架构的麻烦。

标签: python


【解决方案1】:

您可以使用有序的键/值存储,如wiredtiger、leveldb、bsddb。它们都支持使用自定义排序功能的有序键。 leveldb 是最容易使用的,但如果你使用 python 2.7,bsddb is included in the stdlib。如果您只需要字典排序,您可以使用原始 hashopen 函数打开一个持久排序字典:

from bsddb import hashopen


db = hashopen('dict.db')
db['020'] = 'twenty'
db['002'] = 'two'
db['value'] = 'value'
db['key'] = 'key'

print(db.keys())

这个输出

>>> ['002', '020', 'key', 'value']

下班后别忘了关闭数据库:

db.close()

请注意,hashopen 配置可能不适合您的需要。在这种情况下,我建议您使用具有简单 API 的 leveldb 或 Wiredtiger 以提高速度。

要在 bsddb 中按值排序,您必须使用 复合键模式键组合。归结为创建一个字典键,以保持您查找的顺序。在这个例子中,我们首先将原始 dict 值(使小值首先出现)与原始 dict 键(使 bsddb 键是唯一的)打包:

import struct
from bsddb import hashopen

my_dict = {'a': 500, 'abc': 100, 'foobar': 1}

# insert
db = hashopen('dict.db')
for key, value in my_dict.iteritems():
    composite_key = struct.pack('>Q', value) + key
    db[composite_key] = ''  # value is not useful in this case but required
db.close()


# read
db = hashopen('dict.db')
for key, _ in db.iteritems():  # iterate over database
    size = struct.calcsize('>Q')
    # unpack
    value, key = key[:size], key[size:]
    value = struct.unpack('>Q', value)[0]
    print key, value
db.close()

这会输出以下内容:

foobar 1
abc 100
a 500

【讨论】:

  • 酷感谢您提供的所有信息。我决定走 sqlite 的路线,因为我可以在 python 中编写常规 sql,这让我更容易立即认识到如何去做。我相信这些解决方案非常适合。感谢您为我指明正确的方向
猜你喜欢
  • 2014-05-26
  • 2014-11-10
  • 1970-01-01
  • 2010-10-11
  • 2013-06-09
  • 2012-02-18
相关资源
最近更新 更多