Loop over rows of csv.DictReader more than once - python

I open a file and read it with csv.DictReader. I iterate over it twice, but the second time nothing is printed. Why is this, and how can I make it work?
with open('MySpreadsheet.csv', 'rU') as wb:
reader = csv.DictReader(wb, dialect=csv.excel)
for row in reader:
print row
for row in reader:
print 'XXXXX'
# XXXXX is not printed

You read the entire file the first time you iterated, so there is nothing left to read the second time. Since you don't appear to be using the csv data the second time, it would be simpler to count the number of rows and just iterate over that range the second time.
import csv
from itertools import count
with open('MySpreadsheet.csv', 'rU') as f:
reader = csv.DictReader(f, dialect=csv.excel)
row_count = count(1)
for row in reader:
next(count)
print(row)
for i in range(row_count):
print('Stack Overflow')
If you need to iterate over the raw csv data again, it's simple to open the file again. Most likely, you should be iterating over some data you stored the first time, rather than reading the file again.
with open('MySpreadsheet.csv', 'rU') as f:
reader = csv.DictReader(f, dialect=csv.excel)
for row in reader:
print(row)
with open('MySpreadsheet.csv', 'rU') as f:
reader = csv.DictReader(f, dialect=csv.excel)
for row in reader:
print('Stack Overflow')
If you don't want to open the file again, you can seek to the beginning, skip the header, and iterate again.
with open('MySpreadsheet.csv', 'rU') as f:
reader = csv.DictReader(f, dialect=csv.excel)
for row in reader:
print(row)
f.seek(0)
next(reader)
for row in reader:
print('Stack Overflow')

You can create a list of dictionaries, each dictionary representing a row in your file, and then count the length of the list, or use list indexing to print each dictionary item.
Something like:
with open('YourCsv.csv') as csvfile:
reader = csv.DictReader(csvfile)
rowslist = list(reader)
for i in range(len(rowslist))
print(rowslist[i])

add a wb.seek(0) (goes back to the start of the file) and next(reader) (skips the header row) before your second loop.

You can try store the dict in list and output
input_csv = []
with open('YourCsv.csv', 'r', encoding='UTF-8') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
input_csv.append(row)
for row in input_csv:
print(row)
for row in input_csv:
print(row)

Related

Python csv.DictReader. Read alter dictionary then output to file

I need to read in a pipe delimited file change some fields and output. It reads in fine and I am able to change the columns. The writer part writes the header but writerows doesn't write anything. How can I output the updated contents?
csv.register_dialect('pipe',delimiter='|', quoting=csv,QUOTE_NONE)
with open('test.txt') as csvfile
cfile=csv.DictReader(cfile,dialect='pipe')
fieldnames=cfile.fieldnames
for row in cfile:
row['address']=scrubrow(row['address']
with open('c.txt','w') as outfile:
writer=csv.DictWriter(outfile,fieldnames=fieldnames,dialect='pipe')
writer.writeheader()
writer.writerows(cfile)
cfile is an empty iterator. And you discarded all but the last row, so doing row['address']=scrubrow(row['address'] didn't actually do anything.
The simple way to do this is to create a list and use that list:
csv.register_dialect('pipe',delimiter='|', quoting=csv,QUOTE_NONE)
with open('test.txt') as csvfile
reader = csv.DictReader(cfile, dialect='pipe')
fieldnames = cfile.fieldnames
rows = []
for row in reader:
rows.append(scrubrow(row['address']))
with open('c.txt','w') as outfile:
writer = csv.DictWriter(outfile, fieldnames=fieldnames, dialect='pipe')
writer.writeheader()
writer.writerows(rows)
But this will be inefficient because it will require O(N) space. Instead, keeping only a single row in memory at a time, you could do:
csv.register_dialect('pipe',delimiter='|', quoting=csv,QUOTE_NONE)
with open('test.txt') as csvfile, open('c.txt','w') as outfile:
reader = csv.DictReader(cfile,dialect='pipe')
fieldnames = reader.fieldnames
writer = csv.DictWriter(outfile,fieldnames=fieldnames,dialect='pipe')
writer.writeheader()
for row in reader:
writer.writerow(scrubrow(row['address']))

Searching a specific columns of a table for not matching items

with open("test.txt", "r") as test:
reader = csv.reader(test, delimiter="\t")
writer = csv.writer(table, delimiter="\t")
for row in reader:
for field in row:
if field not in keywords:
writer.writerow(row)
break
It seems that this code writes out every row multiple times. I guess that it looks up every single field in each column. How can I specify a single column?
So this is the code I am using right now and it seems that it misses a few rows where the keyword is not present in any column.
table = open("table.txt", "w")
with open("test.txt", "r") as test:
reader = csv.reader(test, delimiter="\t")
writer = csv.writer(table, delimiter="\t")
for row in reader:
if all(field not in keywords for field in row):
writer.writerow(row)
You can use zip to get your columns then.You can use a generator expression within all function for checking that all the elements mett the condition :
with open("test.txt", "r") as Spenn,open("test.txt", "r") as table:
reader = zip(*csv.reader(Spenn, delimiter="\t"))
writer = csv.writer(table, delimiter="\t")
for row in reader:
if all(field not in keywords for field in row):
writer.writerow(row)
But if you just want to write the rows that meet the condition you can use the following code :
with open("test.txt", "r") as Spenn,open("test.txt", "r") as table:
reader = csv.reader(Spenn, delimiter="\t")
writer = csv.writer(table, delimiter="\t")
for row in reader:
if all(field not in keywords for field in row):
writer.writerow(row)

Printing out csv rows apart from first row

I want to read a CSV file in Python, and then print out every row apart from the first row.
I know how to print out all the rows:
with open('myfile.csv', 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter=',')
for row in reader:
print row
And the only way I can think of not printing out the first row is:
with open('myfile.csv', 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter=',')
for i, row in enumerate(reader):
if i != 0:
print row
But this doesn't seem very elegant. Any other solutions?
csv reader objects are iterators, which means you can skip single entries using next():
with open('myfile.csv', 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter=',')
next(reader) # just ignore the result
for row in reader:
print row

Python not entering in for

Why the unique[1] is never accessed in the second for???
unique is an array of strings.
import csv
with open('file.csv', 'rb') as f:
reader = csv.reader(f)
for i in range(len(unique)):
# print unique[i] #prints all the items in the array
for row in reader:
print unique[i] # always prints the first item unique[0]
if row[1]==unique[i]:
print row[1], row[0] # prints only the unique[0] stuff
Thank you
I think it would be useful to go through the program flow.
First, it will assign i=0, then it will read the entire CSV file, printing unique[0] for each line in the CSV file, then after it finishes reading the CSV file, it will go to the second iteration, assigning i=1, and then since the program has finished reading the file, it won't enter for row in reader:, hence it exits the loop.
Further Clarification
The csv.reader(f) won't actually read the file until you do for row in reader, and after that it has nothing more to read. If you want to read the file multiple times, then read it into a list first beforehand, like this:
import csv
with open('file.csv', 'rb') as f:
reader = csv.reader(f)
rows = [row for row in reader]
for i in range(len(unique)):
for row in rows:
print unique[i]
if row[1]==unique[i]:
print row[1], row[0]
I think you might have better luck if you change your nested structure to:
import csv
res = {}
for x in unique:
res[x] = []
with open('file.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
for i in range(len(unique)):
# print unique[i] #prints all the items in the array
if row[1]==unique[i]:
res[unique[i]].append([row[1],row[0]])
#print row[1], row[0] # prints only the unique[0] stuff
for x in unique:
print res[x]

How to read one single line of csv data in Python?

There is a lot of examples of reading csv data using python, like this one:
import csv
with open('some.csv', newline='') as f:
reader = csv.reader(f)
for row in reader:
print(row)
I only want to read one line of data and enter it into various variables. How do I do that? I've looked everywhere for a working example.
My code only retrieves the value for i, and none of the other values
reader = csv.reader(csvfile, delimiter=',', quotechar='"')
for row in reader:
i = int(row[0])
a1 = int(row[1])
b1 = int(row[2])
c1 = int(row[2])
x1 = int(row[2])
y1 = int(row[2])
z1 = int(row[2])
To read only the first row of the csv file use next() on the reader object.
with open('some.csv', newline='') as f:
reader = csv.reader(f)
row1 = next(reader) # gets the first line
# now do something here
# if first row is the header, then you can do one more next() to get the next row:
# row2 = next(f)
or :
with open('some.csv', newline='') as f:
reader = csv.reader(f)
for row in reader:
# do something here with `row`
break
you could get just the first row like:
with open('some.csv', newline='') as f:
csv_reader = csv.reader(f)
csv_headings = next(csv_reader)
first_line = next(csv_reader)
You can use Pandas library to read the first few lines from the huge dataset.
import pandas as pd
data = pd.read_csv("names.csv", nrows=1)
You can mention the number of lines to be read in the nrows parameter.
Just for reference, a for loop can be used after getting the first row to get the rest of the file:
with open('file.csv', newline='') as f:
reader = csv.reader(f)
row1 = next(reader) # gets the first line
for row in reader:
print(row) # prints rows 2 and onward
From the Python documentation:
And while the module doesn’t directly support parsing strings, it can easily be done:
import csv
for row in csv.reader(['one,two,three']):
print row
Just drop your string data into a singleton list.
The simple way to get any row in csv file
import csv
csvfile = open('some.csv','rb')
csvFileArray = []
for row in csv.reader(csvfile, delimiter = '.'):
csvFileArray.append(row)
print(csvFileArray[0])
To print a range of line, in this case from line 4 to 7
import csv
with open('california_housing_test.csv') as csv_file:
data = csv.reader(csv_file)
for row in list(data)[4:7]:
print(row)
I think the simplest way is the best way, and in this case (and in most others) is one without using external libraries (pandas) or modules (csv). So, here is the simple answer.
""" no need to give any mode, keep it simple """
with open('some.csv') as f:
""" store in a variable to be used later """
my_line = f.nextline()
""" do what you like with 'my_line' now """

Categories