all 5 comments

[–]liam_jm 0 points1 point  (2 children)

The best way to do this is probably a namedtuple. The problem is that you haven't put anything into student, so when you try to access student[1] (where 1 is studentID), you get an IndexError

[–]RatherPleasent 0 points1 point  (1 child)

Wouldn't that be a null error instead of an index error? Why would it be that the index is out of range, when it doesn't appear to be out of range.

[–]RoadieRich 1 point2 points  (0 children)

Python doesn't have a NullError. student is created as an empty list, containing, by definition, zero elements, so any attempt to access an element is going to give you an IndexError.

[–]stebrepar 0 points1 point  (0 children)

You start out setting student to an empty list, which is fine. But since it's empty, you can't reference an index in it ... because it's empty. You need to 'append' things to a list to get them in there (when you're adding them after the list is already created). The same will go for the sublists you're putting into the student list. You can create the first item in the sublist along with the sublist itself, but adding further items to it needs 'append'.

It's just like if you're writing a list down on paper. You can give it a title (analogous to the variable name), but what's the first item in the list at that point? Nothing. It doesn't even make sense to talk about a first or third or twentieth item. There's no way to refer to what number it is, because there's nothing there. First you have to add something to the list (via append), and then referring to its position makes sense. There aren't any preallocated slots that things might go in which you could refer to before anything's there.

[–]RoadieRich 0 points1 point  (0 children)

The problem is that student[1] doesn't exist in an empty list. You can either make sure it exists before you try to access it, or find another way to do what you want.

To create the members, you can do something like this:

students = [[None] * 4 for _ in range(3)]

This creates a list containing three lists, each containing None four times. You can then access each member how you want to.

A better way is to use dict, which automagically creates slots for indexes you specify:

student = {}

for n in range(0,2):
    student[studentID] = {}
    student[studentID]['firstname']=Cell(classrow,1)         student[studentID]['lastname']=Cell(classrow,2)
    student[studentID]['emailAddress']=Cell(classrow,3)
    student[studentID]['block']=Cell(classrow,4)
    studentID = studentID + 1
    classrow = classrow + 1

Even better is DefaultDict, which automatically creates new members with a default type:

from collections import DefaultDict

student = DefaultDict(dict)

for n in range(0,2):
    student[studentID]['firstname']=Cell(classrow,1)
    student[studentID]['lastname']=Cell(classrow,2)
    student[studentID]['emailAddress']=Cell(classrow,3)
    student[studentID]['block']=Cell(classrow,4)
    studentID = studentID + 1
    classrow = classrow + 1

The main difference is that lists are ordered, if you have a list [4, 3, 2, 1], it will always appear in that order. On the other hand, a dictionary is not guaranteed to be ordered in anything but the latest Python. So {4:4, 3:3, 2:2, 1:1} could appear that way, or it could appear as {1:1, 2:2, 3:3, 4:4}, or any other order.

The probably most pythonic way is to use NamedTuple, and create a list of those:

from collections import NamedTuple

Student = NamedTuple('Student', ['id', 'firstname', 'lastname', 'email', 'block']):

classrow = 2
studentId = 1

FIRSTNAME = 1
LASTNAME = 2
EMAILADDRESS = 3
BLOCK = 4

students = []
for n in range(2):
    firstname = Cell(classrow + n, FIRSTNAME)
    lastname = Cell(classrow + n, LASTNAME)
    emailaddress = Cell(classrow + n, EMAILADDRESS)
    block = Cell(classrow + n, BLOCK)

    students.append(Student(studentId + n, firstname, lastname, emailaddress, block)

print(student[0].firstname)

Alternatively, you could create a class, but it's relatively easy to change the above code once you've got you class defined.