比dict更快的为python字符串分配索引的方法

2024-04-20 07:38:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要采取一些大文件的字符串和取代每个字符串的id从1起在一个单独的文件。每个文件中都有一些字符串的重复,文件之间也有公共字符串,因此这些字符串需要获得相同的id。我已经用一个字典实现了这一点,它可以工作,但是由于文件的大小和字符串的数量,这个解决方案似乎工作缓慢。有没有一种数据结构或者散列技术更适合这种情况?你知道吗

编辑

我的dict实现

index = {}
lastindex = 0
for row in reader:
    if row[0] not in index:
        lastindex += 1
        index[row[0]] = lastindex
    w.write(index[row[0]])

输入样本

feifei77.w70-e2.ezcname.com
reseauocoz.cluster007.ovh.net
cse-web-cl.comunique-se.com.br
ext-cust.squarespace.com
ext-cust.squarespace.com
ext-cust.squarespace.com
ext-cust.squarespace.com
ghs.googlehosted.com
isutility.web9.hubspot.com
sendv54sxu8f12g.ihance.net
sites.smarsh.io
www.triblocal.com.s3-website-us-east-1.amazonaws.com
*.2bask.com
*.819.cn

这应该会回来

1
2
3
4
4
4
4
5
6
7
8
9
10
...

我要澄清的是,它不一定需要这样排序,尽管它需要包含从1到字符串数的每个整数。 4 2 3 1 1 1 5 6 7 8 9 10也将有效


Tags: 文件字符串incomid数量indexnet
2条回答

代码的瓶颈是for循环期间的w.write。先生成dict,然后写入文件,这样运行速度会快得多。你知道吗

使用set而不是dict对内存稍微友好一些。使用位于https://docs.python.org/3/library/itertools.htmlitertools文档中的unique_everseen()示例,可以执行以下操作:

for idx, word in enumerate(unique_everseen(reader), 1):
    print(idx)

另一种可以扩展到更大数据集的方法是使用某种持久的键/值存储,将数据存储在磁盘上(而不是内存中的映射),例如使用LevelDB(使用Plyvel),它可以如下所示:

import itertools
import plyvel

db = plyvel.DB('my-database', create_if_missing=True)
cnt = itertools.count(1)  # start counting at 1
for word in reader:
    key = word.encode('utf-8')
    value = db.get(key)
    if value is not None:
        # We've seen this word before.
        idx = int(value)
    else:
        # We've not seen this word before.
        idx = next(cnt)
        db.put(key, str(idx).encode('ascii'))

    print(idx)

相关问题 更多 >