使用python3.7进行慢列表解析以去除重复项
Posted
技术标签:
【中文标题】使用python3.7进行慢列表解析以去除重复项【英文标题】:Slow list parsing with python3.7 for duplicate item removal 【发布时间】:2018-10-31 23:02:28 【问题描述】:我正在尝试从一个包含 2.5 亿个 4.4 GB 项目的大型文本文件中删除重复项目。
看到我可以使用以下代码在短短几分钟内将此文件加载到 python 列表中,这让我印象深刻:
x = []
with open("online.txt") as file:
for l in file:
x.append(l)
print('count of array: ')
print(len(x))
但是,当我尝试简单地检查以确保在将下一个项目添加到数组之前不存在时,它需要很多小时才能完成。我觉得我错过了一些可以真正加快速度的简单方法。
这是我用来检查重复项目的代码:
a = []
x = []
with open("online.txt") as file:
for l in file:
if l in a:
print('duplicate')
print(l)
else:
x.append(l.strip())
a.append(l)
print('with duplicates: ');
print(len(a))
print('without duplicates: ')
print(len(x))
这是在具有 64 Gigs 内存和现代双至强处理器的服务器上运行的。
【问题讨论】:
使用列表会很慢!也许尝试将a
设为set()
?
【参考方案1】:
问题在于一个简单的列表,python 每次添加新条目之前都必须搜索每个条目。
您可以尝试使用 python 字典或集合而不是列表。这些数据结构可以更快地确定条目是否已经存在。
只需更改您的代码:
a = # set
x =
with open("online.txt") as file:
for l in file:
if l in a:
print('duplicate')
print(l)
else:
x.add(l.strip()) # add to the set
a.add(l)
你没有指定你的输入文件格式,但是通过将整个数据集加载到一个巨大的字符串中,然后用 python 函数将它拆分,而不是像你在这里那样手动进行,可能会提高速度。
【讨论】:
输入文件是纯文本,每行一个项目由回车分隔。感谢您的想法!words = open("online.txt", "rt").read().replace("\r","").split("\n")
怎么样 - 这至少会读取一大块文件,并给你一个单词列表。很难说它是否会比你已经拥有的更快。【参考方案2】:
最后,这是我用来删除重复项的代码:
x = set([])
with open("all.txt") as file:
for l in file:
x.add(l)
print('count of array: ')
print(len(x))
【讨论】:
请注意,显式循环是不必要的,而且比让 Python 完成工作要慢。set
将任意迭代作为参数并可以使用它,同时进行重复数据删除。只需删除 x
的原始定义和循环,将两者替换为 just do x = set(file)
即可得到相同的结果,但速度快得多。
如果您需要保留顺序,从 CPython 3.6 开始,3.7 作为语言保证,dict
s 保留插入顺序(第一次插入;重复项被忽略),dict.fromkeys
的工作方式非常相似否则到set
构造函数。所以x = dict.fromkeys(file)
会给你一个dict
,其唯一键的顺序与它们第一次看到的顺序相同(在早期版本的 Python 中,你必须使用collections.OrderedDict.fromkeys
)。
@ShadowRanger,使用您的版本需要 133.60 秒,而使用显式循环需要 173.72 秒。也很好地简化了代码。以上是关于使用python3.7进行慢列表解析以去除重复项的主要内容,如果未能解决你的问题,请参考以下文章
2019年6月12日——开始记录并分享学习心得——Python3.7中对列表进行排序