Home > Net >  How to use map on List of lists in python?
How to use map on List of lists in python?

Time:03-20

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 Nones

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)
  • Related