random_user_0891
random_user_0891

Reputation: 2071

python: output data from a list

I'm trying to figure out how to output list items. the code below is taking answers and checking them against a key to see which answers are correct. for each student correct answers are stored in correct_count. Then I'm sorting in ascending order based on the correct count.

  def main():

    answers = [
        ['A', 'B', 'A', 'C', 'C', 'D', 'E', 'E', 'A', 'D'],
        ['D', 'B', 'A', 'B', 'C', 'A', 'E', 'E', 'A', 'D'],
        ['E', 'D', 'D', 'A', 'C', 'B', 'E', 'E', 'A', 'D'],
        ['C', 'B', 'A', 'E', 'D', 'C', 'E', 'E', 'A', 'D'],
        ['A', 'B', 'D', 'C', 'C', 'D', 'E', 'E', 'A', 'D'],
        ['B', 'B', 'E', 'C', 'C', 'D', 'E', 'E', 'A', 'D'],
        ['B', 'B', 'A', 'C', 'C', 'D', 'E', 'E', 'A', 'D'],
        ['E', 'B', 'E', 'C', 'C', 'D', 'E', 'E', 'A', 'D']]

    keys = ['D', 'B', 'D', 'C', 'C', 'D', 'A', 'E', 'A', 'D']

    grades = []

    # Grade all answers
    for i in range(len(answers)):
        # Grade one student
        correct_count = 0
        for j in range(len(answers[i])):
            if answers[i][j] == keys[j]:
                correct_count += 1

        grades.append([i, correct_count])
        grades.sort(key=lambda x: x[1])


            # print("Student", i, "'s correct count is", correct_count)


if __name__ == '__main__':
    main()

if I print out grades the output looks like this

[[0, 7]]
[[1, 6], [0, 7]]
[[2, 5], [1, 6], [0, 7]]
[[3, 4], [2, 5], [1, 6], [0, 7]]
[[3, 4], [2, 5], [1, 6], [0, 7], [4, 8]]
[[3, 4], [2, 5], [1, 6], [0, 7], [5, 7], [4, 8]]
[[3, 4], [2, 5], [1, 6], [0, 7], [5, 7], [6, 7], [4, 8]]
[[3, 4], [2, 5], [1, 6], [0, 7], [5, 7], [6, 7], [7, 7], [4, 8]]

what I'm interested in is the last row. The first number of each set corresponds to a student id and it's sorted in ascending order based on the 2nd number which represents a grade (4, 5, 6, 7, 7, 7, 7, 8).

I'm not sure how to grab that last row and iterate through it so that i get output like student 3 has a grade of 4 and student 2 has a grade of 5

[[3, 4], [2, 5], [1, 6], [0, 7], [5, 7], [6, 7], [7, 7], [4, 8]]

Upvotes: 2

Views: 403

Answers (3)

Sohaib Farooqi
Sohaib Farooqi

Reputation: 5676

While MMelvin0581 already addressed the problem in your code, You can also use nested list comprehension to achieve the same results

>>> [(a,sum([1 if k==i else 0 for k,i in zip(keys,j)])) for a,j in enumerate(answers)]

This will produce output like:

>>> [(0, 7), (1, 6), (2, 5), (3, 4), (4, 8), (5, 7), (6, 7), (7, 7)]

Then you can sort your results based on the criteria

>>> from operator import itemgetter
>>> sorted(out, key=itemgetter(1))

Note: itemgetter will have slight performance benefit over lambda. The above operation will produce output like:

>>> [(3, 4), (2, 5), (1, 6), (0, 7), (5, 7), (6, 7), (7, 7), (4, 8)]

Then finally print your list like:

for item in sorted_list:
    print("Student: {} Scored: {}".format(item[0],item[1]))

Upvotes: 1

MMF
MMF

Reputation: 5921

What about something like the following:

students_grade = {}
for id, ans in enumerate(answers):
    students_grade[id] = sum([x == y for x, y in zip(ans, key)])

Now you have a dictionary with the id of students mapping to their score ;) Of course, you can change the enumerate to have the true list of ids instead!

Upvotes: 2

MMelvin0581
MMelvin0581

Reputation: 503

def main():
    answers = [
    ['A', 'B', 'A', 'C', 'C', 'D', 'E', 'E', 'A', 'D'],
    ['D', 'B', 'A', 'B', 'C', 'A', 'E', 'E', 'A', 'D'],
    ['E', 'D', 'D', 'A', 'C', 'B', 'E', 'E', 'A', 'D'],
    ['C', 'B', 'A', 'E', 'D', 'C', 'E', 'E', 'A', 'D'],
    ['A', 'B', 'D', 'C', 'C', 'D', 'E', 'E', 'A', 'D'],
    ['B', 'B', 'E', 'C', 'C', 'D', 'E', 'E', 'A', 'D'],
    ['B', 'B', 'A', 'C', 'C', 'D', 'E', 'E', 'A', 'D'],
    ['E', 'B', 'E', 'C', 'C', 'D', 'E', 'E', 'A', 'D']]

    keys = ['D', 'B', 'D', 'C', 'C', 'D', 'A', 'E', 'A', 'D']

    grades = []

    # Grade all answers
    for i in range(len(answers)):
        # Grade one student
        correct_count = 0
        for j in range(len(answers[i])):
            if answers[i][j] == keys[j]:
                correct_count += 1

        grades.append([i, correct_count])
        grades.sort(key=lambda x: x[1])

    for student, correct in grades:
        print("Student", student,"'s correct count is", correct)


if __name__ == '__main__':
    main()

What you were doing was printing grades while you were still in the loop. If you would've printed grades after both loops, you would've only seen the last line: [[3, 4], [2, 5], [1, 6], [0, 7], [5, 7], [6, 7], [7, 7], [4, 8]], then just loop through grades and python will "unpack" the list into the student, and grade, respectively ash shown above.

Here is the output:

Student 3 's correct count is 4
Student 2 's correct count is 5
Student 1 's correct count is 6
Student 0 's correct count is 7
Student 5 's correct count is 7
Student 6 's correct count is 7
Student 7 's correct count is 7
Student 4 's correct count is 8

Don't forget to click the check mark if you like this answer.

Upvotes: 2

Related Questions