在Python中使用set()的内存有效方法

时间:2014-12-05 06:01:31

标签: python memory data-structures

我正在研究在Python中重复删除大量字符串的问题,并正在使用sets.Set()解决问题。输入是来自文本文件的一组字符串,输出是删除了重复项的同一组字符串。

脚本需要能够在主内存有限(大约2GB)的机器上运行,问题是集合的大小太大,我的输入是800mb文本文件。

我的部分代码:

for String in InputFile:
    StringSet.add(String)

return StringSet

是否有更有效的解决此问题的方法?我考虑过布隆过滤器和trie,但我更喜欢Set()的O(1)效率。

编辑: 我已经从sets.Set()切换到set(),后者应该更有效,但仍然效率不高。

1 个答案:

答案 0 :(得分:4)

不是存储现有字符串以删除重复项,而是可以执行两种文件机制,在读取一行时计算哈希值,如果哈希值不在现有哈希集中,则该行将被写入输出文件,哈希添加到哈希集中,因为你只需要在任何时候在内存中都有哈希表和单行,这将更有效,除非你的行小于哈希长度。您还应该发现它会快得多,因为比较甚至64字节的哈希条目比比较两行中的所有字符要快得多。

有些事情:

import hashlib
hasher = hashlib.sha1 # You could use md5, SHA224, SHA256, SHA384 or SHA512
hashset = set() # You could also use a list here - speed V size would be interesting
with open(input_name, 'r') as infile:
    with open(output_name, 'w') as outfile:
        for line in infile.readlines():
            h = hasher(line).digest() # Hash the line
            if not h in hashset:
                outfile.write(line)
                hashset.add(h) # if using a list append(h)

唯一的问题是平衡散列类型和大小与重复或碰撞机会之间的长度。有关信息,不同输入的摘要大小(以字节为单位)和声称的相同值的机会是:

Hash Bytes    Security Claim
md5    16     1:2^64
sha1   20     1:2^80
sha224 28 
sha256 32     1:2^128
sha384 48     
sha512 64     1:2^256