# Filtering though a list (Python)

I'm a beginner at Python and I am doing this exercise which reads:

"Define the function Students_at_level that takes a list of Students and a string (representing a class level, e.g., 'FR' or 'SO') and returns a list of students whose class level matches the parameter."

I was given this code:

from collections import namedtuple Course = namedtuple('Course', 'dept num title instr units') # Each field is a string except the number of units ics31 = Course('ICS', '31', 'Intro to Programming', 'Kay', 4.0) ics32 = Course('ICS', '32', 'Programming with Libraries', 'Thornton', 4.0) wr39a = Course('Writing', '39A', 'Intro Composition', 'Alexander', 4.0) wr39b = Course('Writing', '39B', 'Intermediate Composition', 'Gross', 4.0) bio97 = Course('Biology', '97', 'Genetics', 'Smith', 4.0) mgt1 = Course('Management', '1', 'Intro to Management', 'Jones', 2.0) Student = namedtuple('Student', 'ID name level major studylist') # All are strings except studylist, which is a list of Courses. sW = Student('11223344', 'Anteater, Peter', 'FR', 'PSB', [ics31, wr39a, bio97, mgt1]) sX = Student('21223344', 'Anteater, Andrea', 'SO', 'CS', [ics31, wr39b, bio97, mgt1]) sY = Student('31223344', 'Programmer, Paul', 'FR', 'COG SCI', [ics32, wr39a, bio97]) sZ = Student('41223344', 'Programmer, Patsy', 'SR', 'PSB', [ics32, mgt1]) StudentBody = [sW, sX, sY, sZ]

So far I have this code as an attempt to solve this:

def Students_at_level(students: list, level: str) -> list: ''' takes a list of Students and a string, returns students of matching parameter''' for i in students: if level == Student.level: return i assert(Students_at_level([sW, sX, sY, sZ], 'FR') == [sW, sY])

This isn't working. Can anyone guide me in the right direction? Thanks.

## Answers

It should be helpful:

In [1]: mylist = [12, 34, "FR", "Something", "SO"] In [2]: [i for i in mylist if i in ('FR', 'SO')] Out[2]: ['FR', 'SO']

Or use filter for more enhance filter condition:

In [4]: filter(lambda i: i in ('FR', 'SO'), mylist) Out[4]: ['FR', 'SO']

you could use simple list comprehension for this kind of task, example:

>>> a = range(10) >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> [i for i in a if i == 2 or i == 1 ] [1, 2] >>>

As the comment indicates, your function Students_at_level takes a list of Students and a string, and it returns a list of students.

But, you are returning i which is of type Student:

for i in students: if level == Student.level: return i

(I guess you wanted to write i.level instead of Student.level)

You can either change the function into a generator:

def Students_at_level(students, level): for i in students: if level == i.level: yield i

Or simply return a list as intended in the first place. The easy to understand solution would be:

def Students_at_level(students, level): r = [] for i in students: if level == i.level: r.append(i) return r

And the Pythonic way to do it is using a list comprehension:

def Students_at_level(students, level): return [i for i in students if level == i.level]