【问题标题】:Code returns same line multiple times instead of multiple lines代码多次返回同一行而不是多行
【发布时间】:2019-01-26 12:14:12
【问题描述】:

我要做的是打开两个 CSV 文件并仅打印文件 1 和文件 2 中列的内容匹配的行。我已经知道我应该得到 14 个结果,但是我正在使用的 CSV 文件的第一行被打印了 14 次。我哪里做错了?

file1 = open("../dir/file1.csv", "r")
for line in file1:
    file1splitted = line.strip().split(",")

    file2 = open("../dir/file2.csv", "r")
    for line in file2:
        file2splitted = line.strip().split(",")

        for line in file1:
            if file1splitted[0] == file2splitted [2]:
                print (file1splitted[0],file1splitted[1], file2splitted[6], file2splitted[10], file2splitted[12])

file1.close()
file2.close()

【问题讨论】:

  • 您在嵌套循环中践踏了 line 循环变量。这是否是问题的原因,我不确定,但为了清楚起见,我建议使用不同的名称
  • 在 for 循环中打开文件时要小心。可能会给你带来一些麻烦。 (不确定这是否是那里的问题)
  • 我更喜欢将openwith 语句一起使用,以便我知道即使发生错误它也会关闭:with open("../dir/file1.csv", "r") as file1:

标签: python csv output


【解决方案1】:

您应该使用csv module 来读取这些文件,因为以逗号分隔是不可靠的;单个 CSV 列可以包含本身包含逗号的值。

我添加了一些东西来尝试使这个更清洁并帮助您在学习中前进:

  1. 我使用了with 上下文管理器,它会在您阅读完文件后自动关闭文件。不需要.close()
  2. 我已将 csv 读取代码打包成一个函数。现在我们只需要编写一次该部分,就可以使用任何文件调用该函数了。
  3. 我使用csv 模块来读取文件。这将返回一个嵌套的行列表,每个内部列表代表一行。
  4. 我使用了列表推导,这是编写for 循环创建列表的一种更简洁的方法。在本例中,它是 file_1 第一列中所有项目的列表。
  5. 我已将第 4 点中的列表转换为 set。当我们遍历 file_2 时,我们可以非常快速地检查是否在 file_1 中看到了行值(set 查找是 O(1),而不必每次都遍历 file_1)。

我打印的索引来自我自己的测试文件,您需要根据自己的用例调整它们。

import csv

def read_csv(file_name):
    with open(file_name) as infile: # Context manager to auto-close files at end
        reader = csv.reader(infile)
        #next(reader) remove the hash if you want to drop the headers
        return list(reader)


file_1 = read_csv('file_1.csv')
file_2 = read_csv('file_2.csv')

# Make a set of file_1 column 0 with a list comprehension
file_1_vals = set([item[0] for item in file_1])

# Now iterate through file_2
for row in file_2:
    if row[2] in file_1_vals:
        print(row[1])

【讨论】:

    【解决方案2】:
    file1 = open("../dir/file1.csv", "r")
    file2 = open("../dir/file2.csv", "r")
    for line in file1:
        file1splitted = line.strip().split(",")
        for line in file2:
            file2splitted = line.strip().split(",")
            if file1splitted[0] == file2splitted [2]:
                print (file1splitted[0],file1splitted[1], file2splitted[6], file2splitted[10], file2splitted[12])
    
    file1.close()
    file2.close()
    

    如果您提供 csv 文件,那么我可以为您提供更多帮助。

    【讨论】:

    • 这不是读取 CSV 文件的好方法。我们有这个任务的 csv 模块
    • @roganjosh 你说得很对,我的重点是逻辑,为什么 MacRupp 得到错误的结果
    猜你喜欢
    • 2018-03-08
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    相关资源
    最近更新 更多