我有一个包含数百万行的大型文件(1.6演出),这些行的列用以下内容分隔:
[||]
我曾尝试使用csv模块,但它说我只能使用单个字符作为分隔符。所以这就是我所拥有的:
fileHandle = open('test.txt', 'r', encoding="UTF-16")
thelist = []
for line in fileHandle:
fields = line.split('[||]')
therow = {
'dea_reg_nbr':fields[0],
'bus_actvty_cd':fields[1],
'drug_schd':fields[3],
#50 more columns like this
}
thelist.append(therow)
fileHandle.close()
#now I have thelist which is what I want
繁荣,现在我有一个字典列表,它的工作原理。我想要一个清单,因为我关心订单和字典,因为下游它是预期的。这只是感觉就像我应该利用更高效的东西。我不认为这可以很好地扩展到超过一百万行和如此多的数据。所以,我的问题如下:
采用多字符分隔文本文件(UTF-16编码)和创建字典列表的更有效方法是什么?
任何想法都将不胜感激!
答案 0 :(得分:1)
使其更好地扩展的一种方法是使用生成器而不是一次将所有百万行加载到内存中。根据您的使用情况,这可能会也可能不会;如果您只需要对整个数据集进行一次传递,它将最有效。多次传递将要求您以某种形式将所有数据存储在内存中,或者多次从文件中读取它。
无论如何,这里有一个如何使用生成器来解决这个问题的例子:
def file_records():
with open('test.txt', 'r', encoding='UTF-16') as fileHandle:
for line in fileHandle:
fields = line.split('[||]')
therow = {
'dea_reg_nbr':fields[0],
'bus_actvty_cd':fields[1],
'drug_schd':fields[3],
#50 more columns like this
}
yield therow
for record in file_records():
# do work on one record
由于file_records
关键字,函数yield
是生成函数。调用此函数时,它返回一个迭代器,您可以像列表一样迭代。 record
将按顺序返回,每个都是字典。
如果您不熟悉生成器,this是开始阅读它们的好地方。
使得这种规模如此之好的事情是,你一次只能在内存中有一个therow
。基本上发生的事情是,在循环的每次迭代开始时,file_records
函数正在读取文件的下一行并返回计算的记录。在执行工作之前它将等待直到需要下一行,并且除非需要(例如,如果在# do work on one record
中构建的任何数据结构中引用它),之前的记录将不会留在内存中。
另请注意,我已将open
调用移至with
语句。这将确保在迭代完成或引发异常后关闭文件并释放所有相关资源。这比尝试自己捕获所有这些案例并调用fileHandle.close()
要简单得多。