【问题标题】:Nested For loop over csv files嵌套 For 循环遍历 csv 文件
【发布时间】:2017-05-24 20:21:39
【问题描述】:

我有 2 个来自同一来源的 .csv 数据集。我试图检查第一个数据集中的任何项目是否仍然存在于第二个数据集中。

#!/usr/bin/python

import csv
import json
import click

@click.group()

def cli(*args, **kwargs):
    """Command line tool to compare and generate a report of item that still persists from one report to the next."""
    pass

@click.command(help='Compare the keysets and return a list of keys old keys still active in new keyset.')
@click.option('--inone', '-i', default='keys.csv', help='specify the file of the old keyset')
@click.option('--intwo', '-i2', default='keys2.csv', help='Specify the file of the new keyset')
@click.option('--output', '-o', default='results.json', help='--output, -o,   Sets the name of the output.')
def compare(inone, intwo, output):

    csvfile = open(inone, 'r')
    csvfile2 = open(intwo, 'r')
    jsonfile = open(output, 'w')

    reader = csv.DictReader(csvfile)
    comparator = csv.DictReader(csvfile2)
    for line in comparator:
        for row in reader:
            if row == line:
                print('#', end='')
                json.dump(row, jsonfile)
                jsonfile.write('\n')
            print('|', end='')
        print('-', end='')


cli.add_command(compare)

if __name__ == '__main__':
    cli()

假设每个 csv 文件中有 20 个项目。它目前将迭代 40 次并在我期望它迭代 400 次并创建剩余项目报告时结束。

除了迭代之外的一切似乎都在工作。有人对更好的方法有想法吗?

【问题讨论】:

    标签: python-3.x loops csv iterator iterate


    【解决方案1】:

    迭代 40 次听起来差不多 - 当你迭代你的 DictReader 时,你实际上是在迭代包装的文件行,一旦你完成迭代它不会神奇地重置到开头 - 迭代器完成了。

    这意味着您的代码将开始迭代 comparator (1) 中的第一项,然后迭代 reader (20) 中的所有项目,然后从 comparator(1) 中获取下一行),然后它不会在 reader 中迭代任何内容,因此它将转到下一个 comparator 行,依此类推,直到它遍历剩余的比较器行 (18) - 总共有 40 个循环.

    如果您真的想遍历所有行(内存不是问题),您可以将它们存储为列表,然后在启动 for..in 循环时获得一个新的迭代器,所以:

    reader = list(csv.DictReader(csvfile))
    comparator = list(csv.DictReader(csvfile2))
    

    应该给你一个即时修复。或者,您可以在循环后使用csvfile.seek(0) 重置您的reader 'steam'。

    话虽如此,如果您只比较行,并且您希望不会有多少行不同,您可以在 csv.reader() 中加载第一行以获取“标题”,然后放弃 @ 987654331@ 完全通过直接比较线路。然后,当发生更改时,您可以将行弹出到 csv.reader() 以对其进行正确解析,然后将其映射到 headers 表以获取 var 名称。

    这在大型数据集上应该会明显更快,而且通过文件查找可以让您无需在内存中存储比当前 I/O 缓冲区更多的数据。

    【讨论】:

    • 我的实际数据集是一个 58k 行和另一个 580k 行。而且我认为我的计算机上可能只有足够的内存来完成第一种方式。但是,我的数据只会越来越大,所以请您详细说明第二种方法,我试图一次只将每个文件中的一行加载到内存中,但无法弄清楚。感谢您的帮助!
    猜你喜欢
    • 2021-11-20
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 2021-03-04
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    相关资源
    最近更新 更多