chrischrischris
chrischrischris

Reputation: 57

How to turn this into a lambda function?

joe 10 15 20 30 40
bill 23 16 19 22
sue 8 22 17 14 32 17 24 21 2 9 11 17
grace 12 28 21 45 26 10
john 14 32 25 16 89

Using the text file studentdata.txt above, i wrote a program that calculates the average grade for each student, and prints out the student’s name along with their average grade. Here is my code:

with open('studentdata.txt','r') as f:
    for line in f:

        items = line.split()

        total = 0

        grades = items[1:] 

        for grade in grades:

            total = total + int(grade)

        print (items[0], (total/(len(grades))))

It works but I want to make it simpler using lambda functions. How would i go about doing this?

Upvotes: 1

Views: 325

Answers (2)

ForceBru
ForceBru

Reputation: 44838

You can simplify this without lambda functions:

# 1
for line in open('studentdata.txt'):
    items = line.split()
    grades = items[1:] 

    # 2
    total = sum(map(int, grades))

    # 3
    print (items[0], total/len(grades))
  1. You can iterate over files line by line without this overly complex with syntax. You also don't need the 'r' argument as it's the default.
  2. You convert each value in grades to an integer and then sum them.
  3. I removed some unnecessary parentheses.

If you have Python 3.x, you can write even nicer looking code:

for line in open('studentdata.txt'):
    # 1
    name, *grades = line.split()

    # 2
    total = sum(map(int, grades))
    print (name, total/len(grades))
  1. This is just a piece of cake! You extract one value from the list returned by line.split, place it into name and whatever that's left - into a list grades.
  2. You can get rid of the variable total and move the sum(...) right into the call to print to save a line of code, but that'd probably hurt readability, so I don't recommend this.

Upvotes: 1

Jean-François Fabre
Jean-François Fabre

Reputation: 140168

I would build a dictionary (using dictionary comprehension) with key: student name, and value: mean of student mark, splitting according to spaces and defining a lambda to compute the mean (passing a list comprehension of all the values to it, so it can compute sum and len on it without consuming the iterator):

with open(".txt") as f:
    data = [{item.partition(" ")[0]:(lambda x:sum(x)/len(x))([int(x) for x in item.split()[1:]])} for item in f]

result:

[{'joe': 23.0}, {'bill': 20.0}, {'sue': 16.166666666666668}, {'grace': 23.666666666666668}, {'john': 35.2}]

str.partition is used to return the name (splits according to first space character).

So that's a one-liner including: list comprehension, dict comprehension, and lambda. Complex, but logical and performant (the split part is kind of done twice though, since data is heterogenous in the line: name & marks)

Upvotes: 1

Related Questions