1

So I have a list with lots of nested lists in which include a students name and their test score, I was wondering how to retrieve the index (position) of the sub list that contains a specific students scores by searching with the variable 'name' that the user enters when the quiz starts. The lists sub list are created from the import of a text file, the code i used for that is:

with open('class1quizscoreboard.txt') as scoreboard:
    for line in scoreboard:
        importedscores.append(line.strip().split(',')

This works and the list looks like this:

[['EmilyScott ', ' 3'], ['Student Name ', ' 2'], ['Another Student ', ' 1'], ['Third Student ', ' 10']]

So I want to find the sublist by searching with the variable name, then find the position of that sublist IF the name is already in the list of scores. I would then add another test score into the list, but if it is not there just create another list.

I thought of approaching this with an IF with FOR loop, but didn't work

for sublist in importedscores:
if sublist[0] == search:
    print ("Found it!"), sublist

Returned 'not found' even though I used a name I knew was definitely in the list

I am probably approaching this in the complete wrong way but the end goal is to be able to add the students new score to their existing list if they already have one

Thank you for any help

1
  • 1
    You probably want to use a dictionary (or better, a collections.defaultdict), not a list. Commented Mar 2, 2015 at 17:42

2 Answers 2

1

By dictionary:

  1. Read txt file by csv module because file have well define structure.
  2. Create dictionary from the file content where key is name and value is integer number i.e. score
  3. Add new score for existing student.
  4. Create new entry for new sequent.

Demo:

import csv
import pprint
p = "input34.txt"

with open(p, "rb") as fp:
    root = csv.reader(fp, delimiter=',')
    result = {}
    for i in root:
        result[i[0].strip()] = int(i[1].strip())

print "Debug1 result:"
pprint.pprint (result)

serach_key = "Test student"
add_value = 5

if serach_key in result:
    result[serach_key] = result[serach_key] + add_value
else:
    result[serach_key] = add_value

print "Debug2 result:"
pprint.pprint (result)

serach_key = "Another Student"
add_value = 5

if serach_key in result:
    result[serach_key] = result[serach_key] + add_value
else:
    result[serach_key] = add_value

print "Debug3 result:"
pprint.pprint (result)

Output:

vivek@vivek:~/Desktop/stackoverflow$ python 34.py 
Debug1 result:
{'Another Student': 1,
 'Emily Scott': 3,
 'Student Name': 2,
 'Third Student': 10}
Debug2 result:
{'Another Student': 1,
 'Emily Scott': 3,
 'Student Name': 2,
 'Test student': 5,
 'Third Student': 10}
Debug3 result:
{'Another Student': 6,
 'Emily Scott': 3,
 'Student Name': 2,
 'Test student': 5,
 'Third Student': 10}

By list:

Demo:

mport csv
import pprint
p = "input34.txt"

with open(p, "rb") as fp:
    root = csv.reader(fp, delimiter=',')
    result = []
    for i in root:
        result.append([i[0].strip(), int(i[1].strip())])

print "Debug1 result:"
pprint.pprint (result)

serach_key = "Test student"
add_value = 5

add_flag = False
for i,j in enumerate(result):
    if serach_key==j[0]:
        j[1] = j[1] +  add_value
        add_flag = True
        break
if add_flag==False:
    result.append([serach_key, add_value])
print "Debug2 result:"
pprint.pprint (result)

serach_key = "Another Student"
add_value = 5

add_flag = False
for i,j in enumerate(result):
    if serach_key==j[0]:
        j[1] = j[1] +  add_value
        add_flag = True
        break
if add_flag==False:
    result.append([serach_key, add_value])
print "Debug3 result:"
pprint.pprint (result)

Output:

vivek@vivek:~/Desktop/stackoverflow$ python 34.py 
Debug1 result:
[['Emily Scott', 3],
 ['Student Name', 2],
 ['Another Student', 1],
 ['Third Student', 10]]
Debug2 result:
[['Emily Scott', 3],
 ['Student Name', 2],
 ['Another Student', 1],
 ['Third Student', 10],
 ['Test student', 5]]
Debug3 result:
[['Emily Scott', 3],
 ['Student Name', 2],
 ['Another Student', 6],
 ['Third Student', 10],
 ['Test student', 5]]

Use collection.defaultdict to optimize code. So no need to check key is in dictionary or not.

e.g.:

>>> import collections
>>> result = collections.defaultdict(int)
>>> result["student 1"] = 10
>>> result["student 2"] = 20
>>> print result
defaultdict(<type 'int'>, {'student 1': 10, 'student 2': 20})
>>> result["student 2"] = result["student 2"] + 2
>>> print result
defaultdict(<type 'int'>, {'student 1': 10, 'student 2': 22})
>>> result["student 3"] = result["student 3"] + 5
>>> print result
defaultdict(<type 'int'>, {'student 1': 10, 'student 2': 22, 'student 3': 5})
>>> 
Sign up to request clarification or add additional context in comments.

2 Comments

Thankyou for finding a solution! this might be helpful for someone studying more advance solutions but this is too complex for what I am looking for
@Georgia Steele: No, it is not complex, just go step by step, you can easily understand. If not ask me I will tell you. my email id is [email protected]
0

Try this:

def find_index(name,list):
    for i, j in enumerate(list) :
        if name in j :
            return ('{}'.format(i))

for i, j in list:
    if name == i:
        ind = int(find_index(name, list))
        list[ind].append(score)

Here in the find_index function the i represents the index and the j the sublist. - if name in sublist, return the index

In the for loop the i and j represent every subsection in the list. Its a bit hard to explain, but the i is the name and j the score

2 Comments

thank you for your help! Ive put this into my code and no errors have appeared, but it returns the list unedited, could you explain the relevance of 'i' and 'j' in the code and how it works in more detail as I am a beginner.
Ok sure, I'll edit my answer to (try) to explain it. The name searching might not work because it appears that in the list your names have a space on the end of them?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.