[英]slurp/csv/loop a file to create a list of dictionaries
我有一个大文件(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编码)并创建词典列表的更有效方法是什么?
任何想法将不胜感激!
使它更好地扩展的一种方法是使用生成器,而不是一次将所有百万行加载到内存中。 根据您的用例,这可能会或可能不会; 如果您只需要对整个数据集进行一次遍历,则效果最佳。 多次传递将要求您要么以某种形式将所有数据存储在内存中,要么多次从文件中读取数据。
无论如何,这是如何使用生成器解决此问题的示例:
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
由于yield
关键字,函数file_records
是生成器函数。 调用此函数时,它将返回一个迭代器,您可以像列表一样进行迭代。 record
s将按顺序返回,每个记录将是一本字典。
如果您不熟悉发电机,那么这里是开始阅读发电机的好地方。
使这种规模如此之好的原因是,您一次therow
在内存中存储therow
。 本质上发生的是,在循环的每次迭代开始时, file_records
函数正在读取文件的下一行并返回计算的记录。 它会一直等到需要下一行才开始工作,并且除非需要它,否则前# do work on one record
将不会在内存中徘徊(例如,如果您在# do work on one record
构建的任何数据结构中都引用了它,则它# do work on one record
)。
还要注意,我将open
调用移到了with
语句。 这将确保在完成迭代或引发异常后关闭文件并释放所有相关资源。 这比尝试自己捕获所有这些情况并调用fileHandle.close()
简单得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.