如何有选择地将文件行放入列表中

时间:2018-05-14 16:08:12

标签: python python-3.x list

我正在尝试使用以下格式的文件:

# Comments
# More comments

1,foo,bar,1
1,foo,bar,2
21,foo,bar,8

end_of_file

并将其处理为如下列表:

listing = [[1,'foo','bar',1], [1,'foo','bar',2], [21,'foo','bar',8]]

目前,我正在运行类似于:

的内容
listing = [] 
with open('foo_file.cfg','r') as f:
    for line in f:
        if line[0].isDigit:
            listing.append(line)   #  i've also tried listing.append([line])

显然,我最终会:

[['1,foo,bar,1'],['1,foo,bar,2'],['21,foo,bar,8']]

我知道我可以用逗号分割line,重建一个新列表,然后将列表附加到listing.如果这是正确的方法,我绝对愿意这样做,但我认为他们的可能会更清洁。我知道csv模块会将整个文件读成适当的格式,但我不确定如何处理选择性删除某些数据,例如注释。

4 个答案:

答案 0 :(得分:2)

这是使用csv模块的一种方法,它避免明确地计算一些重复性任务(逗号分隔符,换行符等)。

from io import StringIO
import csv

mystr = StringIO("""1,foo,bar,1
1,foo,bar,2
21,foo,bar,8""")

res = []

# replace mystr with open('file.csv', 'r')
with mystr as f:
    reader = filter(None, csv.reader(f))  # ignore empty lines
    for line in reader:
        if line[0].isdigit():
            res.append([int(line[0]), line[1], line[2], int(line[3])])

print(res)

[[1, 'foo', 'bar', 1],
 [1, 'foo', 'bar', 2],
 [21, 'foo', 'bar', 8]]

答案 1 :(得分:1)

您可以在没有任何模块的情况下以类似方式执行此操作:

lst = []
for line in f:
    if not line.startswith('#') and line:
        lst.append([int(i) if i.isdigit() else i for i in line.split(',')])

print(lst)

# [[1, 'foo', 'bar', 1], [1, 'foo', 'bar', 2], [21, 'foo', 'bar', 8]]                                                

答案 2 :(得分:1)

如果最后一行是您想摆脱的唯一一行,可以使用pandas.read_csv属性或error_bad_lines=False

使用skipfooter=1

如果有必要遍历文件的行并检查要导入的行,那么我只需将您追加到listing列表的行更改为

listing.append(line.split(','))

答案 3 :(得分:1)

一种Pythonic方法是使用itertools.dropwhile()忽略满足特定条件的第一行。由于csv.reader对象是迭代器,因此不再需要读取整个文件一次,然后再次循环遍历这些行以将其过滤掉。您也可以通过检查行的验证(not(x)函数中的lambda来删除空行。)

import csv
from itertools import dropwhile

with open('test.csv') as f:
    reader = dropwhile(lambda x: not(x) or x[0].startswith('#'), csv.reader(f))

# print(list(reader))
# [['1', 'foo', 'bar', '1'], ['1', 'foo', 'bar', '2'], ['21', 'foo', 'bar', '8']]