Iterating over csv.reader() in a pythonic way - python

I'm developing a program that reads among other things a csv with csv.reader(). I want to save variables that are matching one of two conditions in two different classvariables. Because i like writing list comprehensions and i'm trying to write my code in a more pythonic way, i was wondering if this is the right approach. csv.reader() seems to be a generator object, because i can iterate over it just once. So for the second condition i'm creating the reader-object a second time. That seems like a ressource waste to me. Of course i could write it with a normal for loop and different if cases. But is there a more pythonic way to write this piece of code?
with open(file, "r") as f:
reader = csv.reader(f, delimiter=",")
self.xitireq = [row[0] for row in reader if "xiti" in row[0]]
with open(file, "r") as f:
reader = csv.reader(f, delimiter=",")
self.apireq = [row[0] for row in reader if "https://www.blabal.de/api" in row[0]]
If i write the code like that, self.apireq is empty:
with open(file, "r") as f:
reader = csv.reader(f, delimiter=",")
self.xitireq = [row[0] for row in reader if "xiti" in row[0]]
self.apireq = [row[0] for row in reader if "https://www.blabal.de/api" in row[0]]

The simplest solution I can think of to do it the way you want is like this
with open(file, "r") as f:
reader = list(csv.reader(f, delimiter=","))
self.xitireq = [x for x in reader if "xiti" in x]
self.apireq = [x for x in reader if "https://www.blabal.de/api" in x]
The only difference here is that I converted your reader to a list, with list(), based on this posting Python import csv to list and this documentation https://docs.python.org/3/library/csv.html#csv.Dialect.
May be more accurate at this point to rename reader to something, but that's just semantics.

Related

Reading CSV and returning array

Taking a video game design course and I've never had to use python before so I am very confused... I am tasked with the following :
read in the CSV file into Python and store its contents as a list of lists
(or 2D list/array). To do so, you will make use of the CSV[1] library.
The reading of the CSV file should be done as its own function - please create a function called readCSV(...)
that takes in the file name as the argument and returns the 2D list.
As mentionned I have no previous coding experience with python. I have managed to do this so far and would greatly appreciate some support.
import csv
# reading each row and printing it
def readCSV(fileName):
TwoDimList = []
with open(fileName, 'r') as f:
r = csv.reader(f, delimiter=',')
for row in r:
entities = readCSV('entities.csv')
print(entities)
Just append each row (which is a list of columns values) to your 2d list and return it in the end:
def readCSV(fileName):
two_dim_list = [] # snake case ftw (PEP8)
with open(fileName, 'r') as f:
r = csv.reader(f, delimiter=',')
# next(r) # skip header line if necessary
for row in r:
two_dim_list.append(row)
return two_dim_list
The short version of that is:
def readCSV(fileName):
with open(fileName, 'r') as f:
r = csv.reader(f, delimiter=',')
# next(r) # skip header line
return list(r)
You can just call list on the reader to get the full 2d list:
def read_csv(file_name):
with open(file_name) as f:
return list(csv.reader(f))
This works because csv.reader is an iterable.
define a function to read csv and return list, and use it later in the program
def readCSVinList(fpath,fname):
with open(fpath+fname) as csv_file:
csv_reader=csv.reader(csv_file)
return list(csv_reader)
f= readCSVinList("A:\\Test\\","test.csv")
for row in f:
print(row)

How to write data onto csv file over a loop in python

I want to write data onto several rows in a csv file. With this code I am only getting a single line written onto file. Need help.
for i in range(1,10):
with open("output.csv",'wb') as f:
writer = csv.writer(f, dialect='excel')
writer.writerow([value1, value2, value3])
You are encountering the error because it is re-writing a csv for every iteration in your loop. You should move the with open() statement outside of your loop block.
Try opening the file only once and then doing the loop:
with open("output.csv",'wb') as f:
writer = csv.writer(f, dialect='excel')
for item in list_A:
writer.writerow([value1, value2, value3])
You would need to use the w option in open as follows:
import csv
list_A = [0,0,0,0,0,0,0,0,0,0,0]
with open("output.csv",'w') as f:
writer = csv.writer(f)
for item in list_A:
writer.writerow([1,0,0,0])

Python: writing an entire row to a CSV file. Why does it work this way?

I had exported a csv from Nokia Suite.
"sms","SENT","","+12345678901","","2015.01.07 23:06","","Text"
Reading from the PythonDoc, I tried
import csv
with open(sourcefile,'r', encoding = 'utf8') as f:
reader = csv.reader(f, delimiter = ',')
for line in reader:
# write entire csv row
with open(filename,'a', encoding = 'utf8', newline='') as t:
a = csv.writer(t, delimiter = ',')
a.writerows(line)
It didn't work, until I put brackets around 'line' as so i.e. [line].
So at the last part I had
a.writerows([line])
Why is that so?
The writerows method accepts a container object. The line object isn't a container. [line] turns it into a list with one item in it.
What you probably want to use instead is writerow.

For loop position in csv reader_Python

In this piece of my script when max_conc is calculated, the next for loop doesn't work unless I put it right after the reader. But doing so, max_conc doesn't work anymore.
with open ('outfile.csv', 'r') as infile:
reader = csv.reader(infile)
max_conc = max(cols[1] for cols in reader)
print max_conc
for row in reader:
print row
Is reopening the input file the only solution?
Because when you called:
max(cols[1] for cols in reader)
You exhausted the iterator, you can't loop through it again. But you can use seek to get back to the beginning of the file:
infile.seek(0)
Or, you can store a copy of the file in the memory:
lines = infile.readlines()
max_conc = max(cols[1] for cols in lines)
Another way, as #Lyncha suggested, loop through a list-copy of the file:
lines = list(reader)
Here's a little example:
>>> f = open('test.txt')
>>> f.read()
'a\nb\nc\nd\ne\nf\ng'
>>> f.read()
'' #whoops, iterator is exhausted
>>> f.seek(0)
>>> f.read()
'a\nb\nc\nd\ne\nf\ng'

How do I create add new items to a dictionary while in a loop?

I'm writing a program that reads names and statistics related to those names from a file. Each line of the file is another person and their stats. For each person, I'd like to make their last name a key and everything else linked to that key in the dictionary. The program first stores data from the file in an array and then I'm trying to get those array elements into the dictionary, but I'm not sure how to do that. Plus I'm not sure if each time the for loop iterates, it will overwrite the previous contents of the dictionary. Here's the code I'm using to attempt this:
f = open("people.in", "r")
tmp = None
people
l = f.readline()
while l:
tmp = l.split(',')
print tmp
people = {tmp[2] : tmp[0])
l = f.readline()
people['Smith']
The error I'm currently getting is that the syntax is incorrect, however I have no idea how to transfer the array elements into the dictionary other than like this.
Use key assignment:
people = {}
for line in f:
tmp = l.rstrip('\n').split(',')
people[tmp[2]] = tmp[0]
This loops over the file object directly, no need for .readline() calls here, and removes the newline.
You appear to have CSV data; you could also use the csv module here:
import csv
people = {}
with open("people.in", "rb") as f:
reader = csv.reader(f)
for row in reader:
people[row[2]] = row[0]
or even a dict comprehension:
import csv
with open("people.in", "rb") as f:
reader = csv.reader(f)
people = {r[2]: r[0] for r in reader}
Here the csv module takes care of the splitting and removing newlines.
The syntax error stems from trying close the opening { with a ) instead of }:
people = {tmp[2] : tmp[0]) # should be }
If you need to collect multiple entries per row[2] value, collect these in a list; a collections.defaultdict instance makes that easier:
import csv
from collections import defaultdict
people = defaultdict(list)
with open("people.in", "rb") as f:
reader = csv.reader(f)
for row in reader:
people[row[2]].append(row[0])
In repsonse to Generalkidd's comment above, multiple people with the same last time, an addition to Martijn Pieter's solution, posted as an answer for better formatting:
import csv
people = {}
with open("people.in", "rb") as f:
reader = csv.reader(f)
for row in reader:
if not row[2] in people:
people[row[2]] = list()
people[row[2]].append(row[0])

Categories