I am trying to solve a problem which has to make a .csv file into list of lists (list1) and then I have to use map function to extract the desired output into another list (list2) from list1
the csv file contains data like
Last name, First name, Final, Grade
Alfalfa, Aloysius,49, D-
Alfred, University,48, D
After making the .csv into list I have to check for the marks if the student will be selected or not by using map on the list1
So here I code it like this
import csv
from curses.ascii import isdigit
def selection(lis):
for x in lis:
if(x.isdigit() and int(x) > 50):
return lis
list1=[]
list2=[]
with open('D:\C \Programs\Advanced Programming\grades.csv', 'r') as csv_file:
csv_reader = csv.reader(csv_file)
next(csv_reader)
for line in csv_reader:
list1.append(line)
for i in list1:
r = map(selection, i)
R = list(r)
list2.append(R)
print(list1)
print(list2)
list1 prints correctly
[['Alfalfa', ' Aloysius', '49', ' D-'], ['Alfred', ' University', '48', ' D ']....]
But my list2 is printing
[[None, None, None, None], [None, None, None, None].....]
I am not getting how to use map on list of lists. Why it is printing none. Please help to solve it.
CodePudding user response:
just update ur selection function as
def selection(lis):
return lis if (lis.isdigit() and int(lis) > 50) else None
map sends a single item to the function not the entire list
Output will be
[['boo', 'foo', '53', 'a']]
[[None, None, '53', None]]
you can return anything else other than None if you want in selection function's else statement
CodePudding user response:
Issue #1
The first problem is that you are going a little too deep. The code
for i in list1:
r = map(selection, i)
is sending individual list items to selection
when you are expecting the entire list
to be sent to selection
. You want to change that code to just be
r = map(selection, list1)
How this results in a bunch of None
s
If you add some print statements around the place to debug what is going on you would see that
for i in list1:
makes i
be a single list such as ['Alfalfa', ' Aloysius', '49', ' D-']
Then map
sends each item from our list i
to the selection
function. So def selection(lis):
doesn't actually recieve a list, it will receive an item from the list such as Alfalfa
or 49
.
Then we have for x in lis:
where we check each character in Alfalfa
to see if it is a number greater than 50
. Is A
greater than 5n, No. Is l
greater than 50
, no. And so on. The for loop finishes, and whenever a function finishes without returning anything, None is returned. Map then moves on to the next item in the list until it gets to a number such as 51
where it will check each character, a 5
and a 1
in this case. Since 5
is not greater than 50
and 1
is not greater than 50
, we continue on. As you can see you will never end up with a number greater than 50
since we are in a little too deep checking each individual character instead of the whole item.
Issue #2
The second problem is you want to use filter instead of map to ignore anything that returns None
. filter
will loop over each item sending each item to selection
and will add the item to our list r
only if selection
returns something true.
The following code does what you want.
import csv
def selection(lis):
for x in lis:
if(x.isdigit() and int(x) > 50):
return True
list1=[]
list2=[]
with open('D:\C \Programs\Advanced Programming\grades.csv', 'r') as csv_file:
csv_reader = csv.reader(csv_file)
next(csv_reader)
for line in csv_reader:
list1.append(line)
r = filter(selection, i)
list2 = list(r)
print(list1)
print(list2)
How I'd solve this type of problem
Below is how I would go about solving this problem. I'm using list comprehension instead of map or filter.
import csv
csv_file = 'D:\C \Programs\Advanced Programming\grades.csv'
with open(csv_file) as fh:
csv_reader = csv.reader(fh)
headers = next(csv_reader)
data = list(csv_reader)
passing_grades = [x for x in data if x.isdigit() and int(x) > 50]
print('passing grades: ', passing_grades)