【问题标题】:python populate a shelve object/dictionary with multiple keyspython用多个键填充搁置对象/字典
【发布时间】:2013-12-26 15:02:30
【问题描述】:

我有一个 4-gram 列表,我想用它填充字典对象/shevle 对象:

['I','go','to','work']
['I','go','there','often']
['it','is','nice','being']
['I','live','in','NY']
['I','go','to','work']

所以我们有类似的东西:

four_grams['I']['go']['to']['work']=1

并且任何新遇到的 4-gram 都填充有它的四个键,值为 1,如果再次遇到,它的值会增加。

【问题讨论】:

  • 这对货架对象有用吗?
  • 它不能在多个级别上工作,只有两个......这当然很有用但完全不同的东西,如果你删除重复的标签,谢谢
  • 这可以通过继承Shelve 对象的__getitem__KeyError 上添加defaultdict 对象来轻松实现。您也可以使用 4 长元组。
  • 这听起来很有趣,但我该怎么做呢?

标签: python dictionary n-gram shelve


【解决方案1】:

你可以这样做:

import shelve

from collections import defaultdict

db = shelve.open('/tmp/db')

grams = [
    ['I','go','to','work'],
    ['I','go','there','often'],
    ['it','is','nice','being'],
    ['I','live','in','NY'],
    ['I','go','to','work'],
]

for gram in grams:
    path = db.get(gram[0], defaultdict(int))

    def f(path, word):
        if not word in path:
            path[word] = defaultdict(int)
        return path[word]
    reduce(f, gram[1:-1], path)[gram[-1]] += 1

    db[gram[0]] = path

print db

db.close()

【讨论】:

  • 看起来也很适合作为解决方案,但如何使用它来更新搁置对象?
  • 它需要是一个货架吗?您能否将字典腌制/转储到 json,然后自己将其保存到文件中?
  • 是的,因为每次运行此代码(我将其用于非常大的数据集)或从文件中写入和读取时都无法继续打开和关闭 pickle 文件,这就是为什么搁置(没有写回) 是一个非常好的解决方案,关键是如何使它与更新多个键一起工作(我认为这可以通过一些临时变量的使用来实现,但仍然无法弄清楚如何准确地做到这一点)
  • 好的,我已经更新了我的答案。我希望这足以让您入门。
【解决方案2】:

您可以创建一个辅助方法,将元素一次插入一个嵌套字典,每次检查所需的子字典是否已经存在:

dict = {}
def insert(fourgram):
    d = dict    # reference
    for el in fourgram[0:-1]:       # elements 1-3 if fourgram has 4 elements
        if el not in d: d[el] = {}  # create new, empty dict
        d = d[el]                   # move into next level dict

    if fourgram[-1] in d: d[fourgram[-1]] += 1  # increment existing, or...
    else: d[fourgram[-1]] = 1                   # ...create as 1 first time

您可以使用以下数据集填充它:

insert(['I','go','to','work'])
insert(['I','go','there','often'])
insert(['it','is','nice','being'])
insert(['I','live','in','NY'])
insert(['I','go','to','work'])

之后,您可以根据需要索引到dict

print( dict['I']['go']['to']['work'] );     # prints 2
print( dict['I']['go']['there']['often'] ); # prints 1
print( dict['it']['is']['nice']['being'] ); # prints 1
print( dict['I']['live']['in']['NY'] );     # prints 1

【讨论】:

  • 是的,你可以将dict初始化为dict = shelve.open('file', writeback=True),这样就可以正常工作了。
  • 是的,writeback=True 的问题是如果数据集很大(这里就是这种情况)我们会遇到内存问题,所以我想避免这种情况
猜你喜欢
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多