What does index of lst even mean?

#46

So I have continued on with the course, just getting answers and studying where I get stuck, it is making MUCH more sense ( this is my personal experience) so perhaps the questions are in the wrong order?

As for someone who has never looked at a coding language in their lives and just started Python yesterday with codecademy. It so far has been extremely fun! everything has been VERY straight forward and codecademy has definitely held my hand along the way!
This specific question as a COMPLETE beginner overwhelmed with terms (in a good way).

The instructions : " The function should double the value of the element at index of lst" its asking us to double the funtion?
In the most basic NOOB explanation of how thus far I understand functions (only 33% into this course) is that a “function” is a little “block of code” that we can “call” upon “to do something”. So the wording here is confusing to me personally, Why/how do I double the thing that I just call upon “to do something”

Below is the answer so I could understand what a PRO did! Again more problems for me! ( as I have continued in the course looking at this is starting to make more sense)
the “lst[index] = lst[index] * 2” confused the HECK outta me! what does “lst[index]” even do? Is it a variable? and why? The square brackets are JUST introduced in learning lists with python and from what we learn this would be a list named “lst” which I guess would be “[3, 8, -10, 12][2] = [3, 8, -10, 12][2] x 2”

#Write your function here
def double_index(lst, index):
if index < len(lst):
lst[index] = lst[index] * 2
return lst

#Uncomment the line below when your function is done
print(double_index([3, 8, -10, 12], 2))

As a pro reading what a noob understands is probably frustrating! Thanks for taking the time to talk to us and I hope I helped if others are confused on the wording as well!

1 Like
#47

It’s asking us to write a function that will take two parameters. a list of some length (not empty) and an index that is in range. The function should access the list at the given index, double its value, then return the list.

a = [3, 7, 10, 15]
b = 2

Lists are zero-indexed meaning the first element is at index 0. We want to the access the list at index 2.

a[b]  => 10

and then double its value,

a[b] = a[b] * 2

or the shorthand assignment operator statement,

a[b] *= 2

will double the value in-place.

When we return the list, the caller should see,

[3, 7, 20, 15]

Note from the above that we are not doubling the function, but a value in the list that we pass to the function to do something with. Nothing happens to the function, just in the function something gets done.

Which is how we avoid repetition and errors, and ensure some measure of predictible consistency. When we know that a snippet of code can always be counted upon to give us reliable results, then wrapping it in a function lets us preserve its integrity, and re-use as often as we need to.

One function can be used a million times. Think how many lines of code that would be if we had to write it for every time we needed it.

By now you are probably catching on. The square brackets are a subscript that contains the index we wish to access in the list. Witness above when we wrote a[2] we accessed the value at index 2 of the list with the name a.

A subscipt should not be confused with the list itself which just happens to be written with square brackets, as well, but with a different meaning. They are delimiters that set the boundaries for the list. When we wish to pass around or store a group of values we cannot simply write,

a = 3, 7, 10, 15

or the computer may interpret it differently than what we intend. Consider,

>>> a = 3, 7, 10, 15
>>> a
(3, 7, 10, 15)
>>> 

This is all new for you so just go along with me, for now. We handed the interpreter a comma separated list of values, and Python had to decide for itself what to do with it so that all the values are preserved. It reaches not for a list wrapper since that would be assuming we want to mutate the data. All it knows how to do is preserve it so we can access it. Nothing in our input says “we want to mutate this list at some later time”.

Python preserved our list of values in a tuple which is ordered (keeps the order we wrote the numbers in) but which is also immutable.

>>> a[2] *= 2
Traceback (most recent call last):
  File "<pyshell#477>", line 1, in <module>
    a[2] *= 2
TypeError: 'tuple' object does not support item assignment
>>> 

We have to tell the interpreter that we want read/write access to the data so we specifify the data structure, a list, [] full knowing that we can mutate the list if we so wish.

[%list elements%][subscript]

In literal terms, that is precisely what we’re doing.

>>> [3, 8, -10, 12][2] * 2
-20
>>> 

However this is not correct in the exact sense,

>>> [3, 8, -10, 12][2] = [3, 8, -10, 12][2] * 2
>>> 

Note that nothing happened that we can see. There are no errors reported but neither can we access the altered list. That’s why we need to assign it back onto the same variable, so we can later recover it.

>>> a = [3, 8, -10, 12]    # cache the original list reference
>>> a[2] *= 2              # mutate the value at index 2
>>> a
[3, 8, -20, 12]            # what will be returned to the caller
>>> 
1 Like
#48

Thank you SO much for taking the time in this post @mtf that seriously helped! im working further into lists now its making a lot more sense. Thanks a ton

1 Like
#49

I think most ppl that get stuck here, confuses “lst” with “1st”, getting obviously overwhelmed with the lesson. So lst in this lesson is the list they want us to create and work with.

The hint talks about len(list). I think at that point everyone should now that len(list) will return the number of elements in a list (the lenght of the list). In this case it would be 4 (looking the the list from the lesson).

An index is the position of an element inside a list (explained before getting here) and they start at zero. so in this lesson: lst[0] = 3 ; lst[1] = 8 ; lst[2] = -10 and lst[3] = 12.

Given these 2 hints, you can ask yourself about ¿how do i make sure if i put a number in the index, it will be inside the list? they just gave you the answer in the hints! if we look at the list, it has 4 element, so the indices goes from zero to 3.
If we make an if like:
if index < len(lst):
This is to ensure that the index we enter as input to the function, is a valid index inside the list (e.g we enter 3, and it will be still < len(lst) which is 4).
Next would be, how do we make the requested operation? well, they asked us to double the value at the given index inside the list right? so lst[index] is what they are asking us to double:
lst[index] = lst[index] * 2
This is what we were asked for. after this you can just return lst to make sure the temporary changes are saved to the list.
So, what about putting a negative input at index? well, at this point i think you haven’t deal with negative indexes, so let’s rewrite the if to make it more focused on what we know until now:
You can use 2 conditions:
if index < len(lst) and index >= 0:
We are limiting the function to work just with positive indexes starting at 0 and finishing at the last index, which will always be 1 number less than the lenght of the list, hence the < len(lst).
Lastly, we were asked to return the original list if the operation cannot be performed (if you input an invalid index); so we can put an else in this case:
else:
return lst
This will save the original list if you enter an index, lets say, -10, or 5.
I have just 20 days learning, and i suggest you to always check the lower left sections Community Forums, even if you know how to do something. You will be glad of how much of extra learning is here in the Forums. Kind Regards…

1 Like
#50

One thing that is important to note once we realize all the minutae above… A list reference is just that, a reference only to the list in its present scope. The function will be seeing this list, not a locally scoped one.

Lists are passed to functions by reference only. That is unless we pass a literal.

foo(['my', 'literal', 'list', 'as', 'the', 'argument'])

If a list is predefined, say,

my_predefined = ['my', 'predefined', 'literal', 'arguments', 'list']

then when we pass it to a function we give a reference to that list

>>> def func(x):
    return map(lambda u: str(u).replace('my', 'our') or u, x)

>>> func(my_predefined)
<map object at 0x02A8E630>
>>> list(func(my_predefined))
['our', 'predefined', 'literal', 'arguments', 'list']
>>> 

We see above that we are able to create a separate list that includes our changes without affecting the reference list.

>>> my_predefined
['my', 'predefined', 'literal', 'arguments', 'list']
>>>
1 Like
#51

Here’s a different way to write this function, using try and except:

def double_index(lst, index):
  try:
    lst[index] = lst[index]*2
    return lst
  except IndexError:
    return lst

print(double_index([3, 8, -10, 12], 2))
#52

Fine and good, except this isn’t a contest looking for submissions. Post to post is frowned on here and one best be advised to not post code without a good explanation to accompany it.

Are you sure IndexError covers the lot? What about TypeError and NameError?

If we are going to go to the extreme of error handling then we best take it to the full extent or not at all. Just saying.

#53

Fair enough. I’m a newbie, sort of feeling around the edges of this problem. Like many others here, I struggled to understand the assignment at first. It seemed to come out of left field, compared to the other assignments

Try and Except is a different way of coding this assignment and it works. In particular, it handles this part of the assignment:

–> If index is not a valid index, the function should return the original list.

We have already learned about error handling in Python using “exceptions” that are caught in “try” blocks and handled in “except” blocks.

In my example, Try and Except handles an invalid index and returns the original lst, just as it supposed to. However, it may be more elegant to accomplish this using an If statement. See [chandrarama674535175] example recently posted. That is probably as close to the “correct” answer as we will see.

If nothing else, this example may help beginners like me to better understand how to use Try and Except. If there is a valid reason NOT to use it in this particular example, I’m all ears!

#54
>>> [][0]
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    [][0]
IndexError: list index out of range
>>> [][a]
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    [][a]
NameError: name 'a' is not defined
>>> [][1.0]
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    [][1.0]
TypeError: list indices must be integers or slices, not float
>>> []['1']
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    []['1']
TypeError: list indices must be integers or slices, not str
>>> 

There is no reason to not use exception handling, but every reason to cover all the bases, not just one.

#55

Super clear.
thanks Mr. Roy

#56

A well put summation. The edges are where we find the special or unexpected cases.

Consider,

What if we start off with no particular error type?

>>> def is_int(n):
    try:
        n = abs(n)
        return range(n + 1)[-1] == n
    except:
        return False

>>> is_int(-1)
True
>>> is_int(0)
True
>>> is_int(1)
True
>>> is_int(1.0)
False
>>> 

Took a while to piece this one together. Wanted to be sure 0 was included in the True results. It is an integer. The main gist is that we don’t have a mind for what type of error triggered the exception, just for what to do if that line is crossed.

The thinking here is to let abs() trigger a type error for non-number else range() trigger the error when it gets anything that isn’t an int class object.

#57

Hello!

It took me some time to understand what the task wants me to do. Because of this sentence.

“The function should double the value of the element at index of lst and return the new list with the doubled value.”

Wouldn’t it be much better and understandable to write it like this:

“The function should double the index number of the element index of list lst and return the new list with the doubled value.”

Or maybe I understood it wrong? Am i wrong here changing at least for myself the sentence? As i understand there are some kind of “serial numbers” of the elements in a list and i need to make a function to double the index/serial number of ‘index’ of the list ‘lst’.

Thanks in advance!

#58

It is the value that we wish to double, not the index number.

  0  1  2  3     # indices
 [2, 5, 8, 9]    # element values

If we double the value at index 2, we get,

[2, 5, 16, 9]

Notice how the indices are serial; i.e., they form a sequence that starts at zero, and increments with each additional element.

Lists are linear and are normally read from left to right. We cannot change the index of an element since it is actually a physical offset. Index 2 is two elements over from the first element; i.e., it has an offset of 2, a literal count.

This is how we maintain ordering. We get to the eighth rung of a ladder by climbing onto the first rung, then the second, &c. on up to the eighth. Note that we start on the ground. The box enclosed by the ground and the first rung is the first element but we didn’t have to leave the ground to get to it.

Of course, ordering can be done also from right to left, but for that we use negative indices. This index cannot start at zero, for obvious reasons: We cannot have two elements with the same index. There is no real magic in it though. We simply use the length as the starting index (the first non-existent element, btw) and subtract one, two, three, &c. on down to negative length.

The last element of a list can be found using this arithmetic…

last_element = the_list[len(the_list) - 1]

We subtract 1 because the element at the_list[len(the_list)] does not exist. We get an index out of range error. We know for sure there is an element when subtract 1 from the length.

To shorten this syntax, Python, and other languages that support negative indexing (some JS methods support it) we simply write,

the_list[-1]

That is the reverse index of the last element in the list.

Our list above which has zero and three positive indices, can also be described with four negative indices.

  0  1  2  3     # indices
 [2, 5, 8, 9]    # element values
 -4 -3 -2 -1     # reverse indices
1 Like
#59

late to the party but completely disagree that people confused have “obviously missed the unit on Lists, and on Lists and Functions.” I have not skipped anything and took the List lesson sequentially meaning I got done that lesson and immediately went to this challenge. I have still not figured it out.

For the record, the way the python3 lesson plan is laid out, it is very easy to go down a rabbit hole learning command line and other tangents put in front of you before you realize you need to go back to the actual lesson. I was off on a tangent for over a week before I got back and had forgotten details on functions.

#60

Can you or someone just tell me (show me here) how to pass the new index value back into the list?

Obviously lst[index] * 2 AND lst[index] *= 2 don’t work. I can’t find anywhere how to pull out a single index number from a list, change it, then put it back into the original list. If there was ever a challenge that needed a video help this is it, at least at 33% through the course.

#61

lst[index] *= 2 doesn’t work??? Can you show the context in which it does not work?

#62

It’s important that we distinguish what is an index and what is a value.

  0  1  2  3      =>  indices (plural for index)
[ 2, 5, 7, 9 ]    => values referenced by index

Example

    a = [2, 5, 7, 9]
    b = 2
    a[b] *= 2
    print (a)    #  [2, 5, 14, 9]
1 Like
#63

Thanks mtf - The biggest confusion came from never being exposed to *= . I had to actually see it work using jupyter on my machine before I “got it”. I don’t recall any instruction using those types of operators up to this point.

def double_index(lst, index):
if index < len(lst):
lst[index] *= 2
return lst
else:
return lst

1 Like
#64

Wait a minute! You’re saying that it is lst as in LST?? not 1st? That has been the problem all along for me. It looks like 1st. omg smh

#65

Same here. Have faithfully followed each lesson, task, challenge, and project as it has directed me to. And now suddenly I’m totally confused as this seems to have just come out of the blue.