繁体   English   中英

slurp / csv /循环文件以创建词典列表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM