删除 CSV 文件中包含所有连字符的行

问题描述 投票:0回答:1

在具有许多其他格式的 CSV 文件中,我无法将连字符 (

-
) 替换为分号 (
;
)。 当我尝试时,我总是遇到错误:
ValueError: i/o operation on closed file.
Attribute Error: 'list' object has no attribute 'split'

input.csv

empty line
empty line
empty line
empty line
empty line
------------------------------------
empty line
empty line
empty line
cars,Date,Daypart,'000 (avg),Share (excluded: Other))
car1,2022-01-01,02:00-02:00,24.459,4.3
car1,2022-01-01,02:01-02:01,20.967,3.7
car1,2022-01-01,02:02-02:02,20.967,3.8
car1,2022-01-01,02:03-02:03,13.029,2.3
car1,2022-01-01,02:04-02:04,13.029,2.3
car1,2022-01-01,02:05-02:05,10.621,1.9
car1,2022-01-01,02:06-02:06,10.621,2.0
car1,2022-01-01,02:07-02:07,10.621,2.0
car1,2022-01-01,02:08-02:08,10.621,2.0

Python代码:

import csv

lines = list()
rownumbers_to_remove = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

with open('input.csv', 'r', encoding="utf-16") as read_file:
    reader = csv.reader(read_file, delimiter=",")
    for row_number, row in enumerate(reader, start=1):
        if row_number not in rownumbers_to_remove:
            lines.append(row)

with open('output.csv', 'w', newline='', encoding="utf-8") as write_file:
    writer = csv.writer(write_file, delimiter=";")
    writer.writerow(['column1', 'column2', 'column3', 'column4', 'column5', 'column6', 'column7', 'column8'])
    writer.writerows(lines)

我尝试寻找以前的解决方案,但没有一个有效。

编辑:

我尝试将其拆分为:

lines = list()
lines_ = lines.split('-')

错误信息:

lines_ = lines.split('-')
             ^^^^^^^^^^^
AttributeError: 'list' object has no attribute 'split'

或者我尝试更换它:

with open('output.csv', 'w', newline='', encoding="utf-8") as write_file:
    writer = csv.writer(write_file, delimiter=";")
    writer.writerow(['column1', 'column2', 'column3', 'column4', 'column5', 'column6', 'column7', 'column8'])
    for row in read_file:
        lines = row.replace("-", ";")
    writer.writerows(lines)

错误信息:

 for row in read_file:
ValueError: I/O operation on closed file.

所以实际上我不知道如何解决这个问题以及在哪里使用

split()
/
replace()
方法。

python csv
1个回答
0
投票

您正在尝试拆分一个空列表,而不是行集合。当然,你应该能够看到

lines = list()
lines_ = lines.split('-')

在功能上等同于

lines_ = list().split('-')

这根本没有意义,并且显然会产生你得到的错误;您可以

.split
包含连字符的字符串(因此
"foo-bar-baz".split('-')
生成列表
['foo', 'bar', 'baz']
),但这根本不是字符串。

(如果列表 did

split
方法,大概需要您拆分必须完全匹配的列表成员;所以从理论上讲,也许
['foo', 'bar', 'baz'].split('bar')
是有意义的。但是列表没有这个方法,所以我们不要再继续沿着这条路走下去了。)

有点类似,第二条错误消息清晰可见;您正在尝试循环

read_lines
,但这是一个关闭的文件句柄,您无法再从中读取。当你退出第一个
with
上下文时,它就关闭了,无论你在开始时调用
.close()
,它都会在最后隐式地调用
open(...) as

无论如何,如果我们可以假设要丢弃的行不包含任何分隔符,那么根本问题就很容易解决。只需阅读并丢弃,直到看到具有多个字段的行:

with open('input.csv', 'r', encoding="utf-16"
        ) as read_file, open('output.csv', 'w', newline='', encoding="utf-8"
        ) as write_file:
    reader = csv.reader(read_file, delimiter=",")
    writer = csv.writer(write_file, delimiter=";")
    for row in reader:
        if len(row) == 1:
            continue
        writer.writerow(row)

如果您确实想对行号列表进行硬编码,那么应该很容易了解如何使其适应您的

enumerate()
方法。

更详细一点,

        if len(row) == 1:
            continue

如果当前行不包含逗号,则通过跳过该行循环的其余部分来丢弃当前行;即不对输出执行

writerow

(这也会将格式从逗号分隔更改为分号分隔。您的问题并未揭示这是实际要求还是错误;我假设您有意识地包含了此更改。)

通过不将所有行收集到内存中,这还可以提高速度和鲁棒性。相反,我们读,可能写,然后一次忘记一行。

© www.soinside.com 2019 - 2024. All rights reserved.