#python #csv
#python #csv
Вопрос:
Я имею дело с CSV-файлом, похожим на этот
foo; val1; position1
bar; name1; address1; phone_nbr1
bar; name2; address2; phone_nbr2
foo; val2; position2
bar; name3; address3; phone_nbr3
bar; name4; address4; phone_nbr4
bar; name5; address5; phone_nbr5
bar; name6; address6; phone_nbr6
foo; val3; position3
Излишне говорить, что я не могу изменить CSV.
Экземпляры, отображаемые в foo
строках, отличаются от экземпляров со bar
строками (обратите внимание, что у них даже разное количество полей)
Мне нужно просто прочитать эти данные, не нужно их записывать.
Моей первой идеей было разделить файл на два временных файла, а затем прочитать каждый из них отдельно с помощью a csv.DictReader
, однако мне действительно не нравится этот подход.
Есть ли более простой способ сделать это? Я хотел бы, по возможности, избежать необходимости записывать файлы на диск.
Для справки, я использую Python2.7 на машине Solaris 10.
Ответ №1:
Вы можете собирать записи из a csv.reader
в двух разных списках, в зависимости от их длины (или любого другого критерия, который вы используете для различения двух потоков):
list1 = []
list2 = []
with open("input.csv", "rb") as f:
for record in csv.reader(f, delimiter=";"):
if len(record) == 3:
list1.append(record)
else:
list2.append(record)
Ответ №2:
csv.reader()
с этим проблем нет:
import csv
foo = []
bar = []
with open("test.csv", 'r') as f:
c = csv.reader(f, delimiter = ";")
for row in c:
if row[0] == "foo":
foo.append(row[1:])
elif row[0] == "bar":
bar.append(row[1:])
print(foo)
print(bar)
результаты в
[[' val1', ' position1'], [' val2', ' position2'], [' val3', ' position3']]
[[' name1', ' address1', ' phone_nbr1'], [' name2', ' address2', ' phone_nbr2'], [' name3', ' address3', ' phone_nbr3'], [' name4', ' address4', ' phone_nbr4'], [' name5', ' address5', ' phone_nbr5'], [' name6', ' address6', ' phone_nbr6']]
Ответ №3:
Как насчет простого использования str.split
в каждой строке?
items = line.split(";")
Затем, если первый элемент в items
списке — foo
вы делаете что-то одно, а если bar
вы делаете что-то другое.
Ответ №4:
Тот факт, что строки разные, не является проблемой для csv
module, но вам придется анализировать содержимое строки по-разному в зависимости от первой «ячейки».
Пример кода:
with open(input_file, 'rb') as fin:
c = csv.reader(fin)
for line in c:
if line[0] == 'foo':
# do some treatment
elif line[0] == 'bar':
# do something else
c.close()
Ответ №5:
Из вашего вопроса неясно, чего вы на самом деле хотите достичь, но я не уверен, что вам нужен модуль csv здесь.
for row in myfile.readlines():
cols = [r.strip() for r in row.split(';')]
if (cols[0] == "foo"):
# Do something for foo
elif (cols[0] == "bar"):
# Do something for bar
Ответ №6:
Как насчет чего-то вроде:
foos = []
bars = []
for line in csv.reader(open("file.csv","rb"), delimiter=";"):
if line[0] == "foo":
foos.append(Foo(line[1], line[2]))
else:
bars.append(Bar(line[1], line[2], line[3]))
Предполагая, что у вас есть класс a Foo
и a Bar
, принимающий остальные ячейки строки в качестве аргументов.