I am in the process of learning Python, which is my first real experience with programming. I have been working through a series of lessons found here.
The lesson I am on is concerned with nesting loops. However, in one exercise they offer a solution to the problem by essentially renaming the indices of the list items. Keep in mind, this is not a dictionary being used. While these lessons have been going great, this one answer to the problem baffles me as there is no explanation of what is going on. Furthermore, I cannot seem to find reference to this technique anywhere else in the lessons series, or elsewhere.
Here is what the exercise is asking me to do. 1 "Write a program which uses a nested for loop to populate a three-dimensional list representing a calendar: the top-level list should contain a sub-list for each month, and each month should contain four weeks. Each week should be an empty list. 2 Modify your code to make it easier to access a month in the calendar by a human-readable month name, and each week by a name which is numbered starting from 1. Add an event (in the form of a string description) to the second week in July.
The first part was no problem. The second part was a bit challenging given the parameters, but the answer given was not what I expected.
I've seen explanations on stack overflow of using dictionaries to accomplish this sort of naming indices goal: Python: can I have a list with named indices?
However, here was the solution offered:
(JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER) = range(12)
(WEEK_1, WEEK_2, WEEK_3, WEEK_4) = range(4)
calendar = []
for m in range(12):
month = []
for w in range(4):
month.append([])
calendar.append(month)
calendar[JULY][WEEK_2].append("Go on holiday!")
print(calendar)
Can someone explain how this works exactly? I find it odd that the month and week names do not have to be strings, but rather just variable names. I think each variable name is being assigned to each item in the particular range defined. However, I'm surprised that variable names can be used as the list indices. Once this is done, I cannot refer to an index by numerical value anymore. For example, I cannot use:
calendar[1][1].append("This is the first week of January.")
I am further confused by this because when I write a simple loop after the last line:
for i in range(12):
print(i)
I get a print out of numbers 0 through 11 as usual, but not these variable names.
What's going on exactly, and how does this work?
Declaring a list of variables like this:
(WEEK_1, WEEK_2, WEEK_3, WEEK_4) = range(4)
is a way of storing multiple values to multiple variables. It is the same as doing this:
(WEEK_1, WEEK_2, WEEK_3, WEEK_4) = (0,1,2,3)
or this:
WEEK_1 = 0
WEEK_2 = 1
WEEK_3 = 2
WEEK_4 = 3
range(4) returns a list of integers from 0 to 3.
range(4) == (0,1,2,3)
In python, it is possible to write a list of variables as the left operand and assign values to them by writing a list of data on the right operand. In this case, the first variable of the list on the left will store the value of the first piece of data on the right, the second variable on the left will store the value of the second piece of data on the right and so on.
In your exercise, the months and weeks are only stored in memory as integers. These integers have all been stored in variables whose names are representative of what each value depicts.
Contrary to what you have said, calendar[1][1].append("First week of January")
does work. Technically, the first week of January is in calendar[0][0]
because the indexes of lists start at 0. The reason for this is because as we stated earlier, WEEK_1, WEEK_2
etc. are variable names in which integers are stored. Accordingly the same exact thing happens with the months as well. When you say calendar[JULY][WEEK_2]
it is the exact same thing as saying calendar[7][1]
, only now you've stored these numbers into more readable variables so the code is more representative of what it does and easier to read.