使用Python读取CSV文件时如何跳过空行

21
这是我的代码,我可以打印出每一行,但由于 CSV 文件格式的缘故,当出现空白行时它会打印分号“;”,所以我想要在出现空白行时跳过它。
这是我的代码,我能够打印每一行,但当出现空行时,由于CSV文件格式的原因会打印分号";",所以我想在出现空行时跳过它。
import csv
import time

ifile = open ("C:\Users\BKA4ABT\Desktop\Test_Specification\RDBI.csv", "rb")
for line in csv.reader(ifile): 
    if not line: 
        empty_lines += 1 
        continue
    print line

为什么要以二进制模式打开文件?不管怎样,你应该迭代data变量中的行。在没有先声明的情况下,对empty_lines进行赋值是不正确的,并且你在for循环中有一个额外的闭合括号的拼写错误。 - Birei
那段代码没有输出任何内容,因为文件在for循环之前已经被读入到了data中。 - Janne Karila
Janne,是的,你说得对,它没有打印任何东西,但实际上我已经尝试过打印单个单元格,这就是为什么我将其存储在数组中的原因。 - ketan
2
@Birei:“为什么要以二进制模式打开文件?”因为这是在Python 2中打开文件并传递给csv.reader的正确便携式方法,正如文档中所述。 - DSM
你可以使用类似于这个答案的过滤器或生成器方法:https://dev59.com/vGYq5IYBdhLWcg3w0j8T#14158869 我建议重构一些逻辑到 def is_empty_line(line): ... 中以提高可读性,比如说如果你想跳过一个包含所有空格的行。而且跳过注释和空行也是个好主意 - 更多理由来将其重构为单独的函数。 - Leonid
8个回答

16
如果你想跳过所有的空白行,你应该使用这个测试:' '.isspace()
既然你可能想要做一些比仅仅将非空白行打印到控制台更复杂的事情(不需要使用CSV模块来完成),这里有一个涉及DictReader的示例:
#!/usr/bin/env python
# Tested with Python 2.7

# I prefer this style of importing - hides the csv module
# in case you do from this_file.py import * inside of __init__.py
import csv as _csv


# Real comments are more complicated ...
def is_comment(line):
    return line.startswith('#')


# Kind of sily wrapper
def is_whitespace(line):
    return line.isspace()


def iter_filtered(in_file, *filters):
    for line in in_file:
        if not any(fltr(line) for fltr in filters):
            yield line


# A dis-advantage of this approach is that it requires storing rows in RAM
# However, the largest CSV files I worked with were all under 100 Mb
def read_and_filter_csv(csv_path, *filters):
    with open(csv_path, 'rb') as fin:
        iter_clean_lines = iter_filtered(fin, *filters)
        reader = _csv.DictReader(iter_clean_lines, delimiter=';')
        return [row for row in reader]


# Stores all processed lines in RAM
def main_v1(csv_path):
    for row in read_and_filter_csv(csv_path, is_comment, is_whitespace):
        print(row)  # Or do something else with it


# Simpler, less refactored version, does not use with
def main_v2(csv_path):
    try:
        fin = open(csv_path, 'rb')
        reader = _csv.DictReader((line for line in fin if not
                                  line.startswith('#') and not line.isspace()),
                                  delimiter=';')
        for row in reader:
            print(row)  # Or do something else with it
    finally:
        fin.close()


if __name__ == '__main__':
    csv_path = "C:\Users\BKA4ABT\Desktop\Test_Specification\RDBI.csv"
    main_v1(csv_path)
    print('\n'*3)
    main_v2(csv_path)

3
注意:此方法可能会破坏带有引号字段内换行符的文件。在这种情况下,文件中的行数不能与分隔记录的数量相比较。请参见CSV模块文档,并查看页面底部的解释。 - ASL

13

与其

if not line:

这应该可以工作:

if not ''.join(line).strip():

我对我的问题使用了类似的方法,谢谢,非常优雅的检查方式 :) - Apollo Data

5

我的建议是使用csv阅读器将文件分隔成行。这样,您只需检查该行是否为空,如果是,则继续执行。

import csv

with open('some.csv', 'r') as csvfile:

    # the delimiter depends on how your CSV seperates values
    csvReader = csv.reader(csvfile, delimiter = '\t')

    for row in csvReader:
        # check if row is empty
        if not (row):    
            continue

5

您可以始终检查逗号分隔值的数量。这似乎更加高效和有效。

当迭代地阅读这些行时,由于它们是逗号分隔值列表,您将得到一个列表对象。因此,如果没有元素(空链接),那么我们可以使其跳过。

        with open(filename) as csv_file:
          csv_reader = csv.reader(csv_file, delimiter=",")
          for row in csv_reader:
            if len(row) == 0:
                continue

1
import csv

with open('userlist.csv') as f:

    reader = csv.reader(f)
    user_header = next(reader)       # Add this line if there the header is

    user_list = []                   # Create a  new user list for input
    for row in reader:
        if any(row):                 # Pick up the non-blank row of list
            print (row)              # Just for verification
            user_list.append(row)    # Compose all the rest data into the list

next(reader) 就足够了,不需要为它分配一个变量。 - Pedro Lobito

1
您可以去除前导和尾随空格,如果在此之后长度为零,则该行为空。

4
通过使用if not line.strip():语句来判断一行是否为空。 - Johannes Charra
一个 "空白" 的 CSV 行看起来像这样:,,,,,,,,,,,,,,,,,,,因此,更好的方法是用逗号分割,用空字符串拼接,然后剥离并查看是否有任何内容留下。 - Apollo Data

1
这个例子只是以数组形式打印数据,同时跳过空行:
import csv

file = open("data.csv", "r")
data = csv.reader(file)

for line in data:
    if line: print line

file.close()

我发现这个例子比其他提供的例子更清晰易懂。

0
import csv
ifile=csv.reader(open('C:\Users\BKA4ABT\Desktop\Test_Specification\RDBI.csv', 'rb'),delimiter=';')
for line in ifile:
    if set(line).pop()=='':
        pass
    else:
        for cell_value in line:
            print cell_value

1
不符合Python风格。除此之外:set("\n").pop() == '\n',因此带有换行符的空行仍将被打印。 - Johannes Charra
@srinu j 谢谢,我可以跳过空行,但之后我如何访问单个单元格的值呢?我知道如果我可以将文件存储在“列表”中,那么我就可以访问,但问题是我也会得到空行。 - ketan
当你迭代文件中的行时,它会返回一个列表,你可以通过 line[0] 访问该列表的第一个值。 - Srinivasreddy Jakkireddy
@Srinu J,我已经尝试获取整个列的输出,但我想在迭代行时访问单个单元格值。 - ketan
迭代行并打印单元格值。 - Srinivasreddy Jakkireddy
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接