【问题标题】:Storing a large dictionary with non-unique key-value pairs存储具有非唯一键值对的大型字典
【发布时间】:2015-02-13 21:04:08
【问题描述】:

我有一个大的(超过一百万个字符)这种形状的文本文件:

'abc' 2
'nmb' 3
'sds' 5
'abc' 6

如您所见,每一行都有两个元素。每行上的对不是唯一的,这意味着“abc”可以映射到 2 和 3 甚至更多。我需要将其存储到可以保存到文件中的合适数据结构中。稍后我想看看一个字符串出现了多少次,以及它被映射到某个数字的次数。我需要能够相对快速地做到这一点,否则我可以按原样使用文件。

我首先尝试使用json 库创建一个字典并存储数据,这非常简单直接。但后来我意识到我不能使用它,因为键值对不是唯一的,一个键可以映射到多个值,并且数据结构应该保留它。

所以考虑到文件的大小和我想要使用它的方式,有什么好的方法来做到这一点?

【问题讨论】:

    标签: python python-3.x dictionary


    【解决方案1】:

    lists 中的dict 怎么样?:

    { 
        'abc': [2, 6],
        'nmb': [3],
        'sds': [5]
    }
    

    在进一步了解 OP 的用例后进行编辑:您也可以这样做:

    {
        'abc': {2: 3, 6: 7},
        'nmb': {3: 1},
        'sds': {5: 1},
    }
    

    您还可以使用其他答案中提到的defaultdictcollections.Counter 来快捷地完成某些工作。

    【讨论】:

    • 这很好,但问题是,我还需要关注某个键在整个文本中出现了多少次,这样信息就丢失了。
    • @mu 我修好了。 OP:我认为这个想法是每次在文件中出现另一个'abc' 行时,您都会附加到相应的列表中,因此该列表的len() 会告诉您该键出现了多少次。
    • 并非如此。 'abc' 可能已经映射到 2 三次和 6 次七次,但我仍然会得到两个 len。我需要这些信息。
    • 那么'abc': [2, 6], 实际上就是'abc': [2, 2, 2, 6, 6, 6, 6, 6, 6, 6],
    • 也许您应该使用collections.Counter 而不是字典中的列表。这将计算每个整数的出现次数。
    【解决方案2】:

    一个字符串出现了多少次,它被映射到某个数字的次数。

    如果这是您要解决的具体问题,我会尝试使用 dict 将字符串映射到 collection.Counter 实例。然后,您可以通过字符串键和数字键轻松查找(以获取“计数”值)(data['abc'][2] -> 1),或者通过字符串键查找并将计数器的值相加以获得总出现次数 (sum(data['abc'].values()) -> 2)。

    【讨论】:

      【解决方案3】:

      您可以在此处使用defaultdict

      from collections import defaultdict
      
      data = defaultdict(list)
      with open("input.txt", "rb") as f:
          for line in f:
              key, value = line.split()
              data[key].append(value)
      

      defaultdict 的优点是您不需要为遇到的每个新键都初始化一个空列表。

      找出一个键出现了多少次是一个简单的len(data[key]) 语句。

      在将其保存回来时,pickle 它,或者每个键都有一个条目,在文件中使用逗号分隔值,以便您以后可以快速重建它:

      with open("output.txt", "wt") as f:
          for key in data:
              f.write("{} {}\n".format(key, ','.join(data[key])))
      

      【讨论】:

        猜你喜欢
        • 2012-03-15
        • 1970-01-01
        • 1970-01-01
        • 2019-10-31
        • 2021-12-19
        • 1970-01-01
        • 2019-06-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多