Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #62176 > unrolled thread
| Started by | Peter Otten <__peter__@web.de> |
|---|---|
| First post | 2013-12-17 11:51 +0100 |
| Last post | 2013-12-17 11:51 +0100 |
| Articles | 1 — 1 participant |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: Reading csv file Peter Otten <__peter__@web.de> - 2013-12-17 11:51 +0100
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-12-17 11:51 +0100 |
| Subject | Re: Reading csv file |
| Message-ID | <mailman.4275.1387277432.18130.python-list@python.org> |
Igor Korot wrote:
> Hi, guys,
>
> On Tue, Dec 17, 2013 at 12:55 AM, Peter Otten <__peter__@web.de> wrote:
>> Peter Otten wrote:
>>
>>> You are still reading the complete csv file. Assuming
>>>
>>> (1) the first row of the csv contains the column names
>>> (2) you want to skip the first five rows of data
>
> Looking at the Peter's reply I realized I missed very important piece:
>
> The first row may or may not contain column names.
> If it does not, the first row will just contain some text, i.e. "abc"
> and the column names will be located on the row 6.
>
> I know if does complicate things but I am deeply sorry.
> The csv file is generated by some program run and I guess depending on
> the switches passed to
> that program it either creates the header in the csv (report name,
> time slice it ran at, user it ran under
> and some other info.
> Or it can be run without such switch and then it generates a normal csv.
>
> The report it generates is huge: it has about 30+ fields and I need to
> read this report, parse it and
> push accordingly to the database of mySQL.
>
> Thank you for any suggestions and sorry for not posting complete task.
Try the following (without the mock-ups of course):
$ cat csv_skip_header.py
import csv
import sys
from contextlib import contextmanager
filename = "ignored"
@contextmanager
def open(*args):
"mock-up, replace with open() built-in"
from StringIO import StringIO
lines = range(10)
if len(sys.argv) > 1 and sys.argv[1] == "--skip":
lines[0] = "skipped"
lines[6] = "field1-from-line6,field2-from-line6"
else:
lines[0] = "field1-from-line1,field2-from-line1"
yield StringIO("\r\n".join(map(str, lines)))
def is_arbitrary_text(fieldnames):
"mock-up, replace with the actual check"
return "skipped" in fieldnames
with open(filename, "rb") as f:
reader = csv.DictReader(f)
if is_arbitrary_text(reader.fieldnames):
for _ in range(5):
next(reader, None)
reader._fieldnames = None # underscore necessary,
# fieldnames setter doesn't work
reader.fieldnames # used for its side-effect
for row in reader:
print row
$ python csv_skip_header.py
{'field2-from-line1': None, 'field1-from-line1': '1'}
{'field2-from-line1': None, 'field1-from-line1': '2'}
{'field2-from-line1': None, 'field1-from-line1': '3'}
{'field2-from-line1': None, 'field1-from-line1': '4'}
{'field2-from-line1': None, 'field1-from-line1': '5'}
{'field2-from-line1': None, 'field1-from-line1': '6'}
{'field2-from-line1': None, 'field1-from-line1': '7'}
{'field2-from-line1': None, 'field1-from-line1': '8'}
{'field2-from-line1': None, 'field1-from-line1': '9'}
$ python csv_skip_header.py --skip
{'field1-from-line6': '7', 'field2-from-line6': None}
{'field1-from-line6': '8', 'field2-from-line6': None}
{'field1-from-line6': '9', 'field2-from-line6': None}
You may find the following a bit cleaner:
with open(filename, "rb") as f:
reader = csv.reader(f)
fieldnames = next(reader)
if is_arbitrary_text(fieldnames):
for _ in range(5):
next(reader, None)
fieldnames = None
reader = csv.DictReader(f, fieldnames=fieldnames)
for row in reader:
print row
Or you do the skipping on the file (only if the rows don't have embedded
newlines).
Back to top | Article view | comp.lang.python
csiph-web