0

Hay fellow programmers,

I'm new to programming and was wondering if someone could help clear something up for me? I'm not sure if it's because of the way it's written or if it is simply a real, but contradictory way of doing something.

I'm currently learning Python from the book 'Learn Python in One Day' and their explanation of list slicing has confused me. At the beginning, they state individual indexes always start from zero, but in a later example they seem to be using '1' as the starting point(?) and ending at index 5 - 1?

The example they're using for below is: userAge = [21, 22, 23, 24, 25]

At the beginning, in the extract below, they explain that the index for 21 = 0, the index for 22 = 1, 23 = 2, 24 = 3, and 25 = 4.

But when they get to the bottom of the extract they are talking about a 5th index (despite there not being one in the example above)...

Here's the extract from the book. I've highlighted the bits that have confusticated me:

"Individual values in the list are accessible by their indexes, and indexes always start from ZERO, not 1. This is a common practice in almost all programming languages, such as C and Java. Hence the first value has an index of 0, the next has an index of 1 and so forth. For instance, userAge[0] = 21, userAge[1] = 22.

Alternatively, you can access the values of a list from the back. The last item in the list has an index of -1, the second last has an index of -2 and so forth. Hence, userAge[-1] = 25, userAge[-2] = 24.

You can assign a list, or part of it, to a variable. If you write userAge2 = userAge, the variable userAge2 becomes [21, 22, 23, 24, 25].

If you write userAge3 = userAge[2:4], you are assigning items with index 2 to index 4-1 from the list userAge to the list userAge3. In other words, userAge3 = [23, 24].

The notation 2:4 is known as a slice. Whenever we use the slice notation in Python, the item at the start index is always included, but the item at the end is always excluded. Hence the notation 2:4 refers to items from index 2 to index 4-1 (i.e. index 3), which is why userAge3 = [23, 24] and not [23, 24, 25].

The slice notation includes a third number known as the stepper. If we write userAge4 = userAge[1:5:2], we will get a sub list consisting of every second number from index 1 to index 5-1 because the stepper is 2. Hence, userAge4 = [22, 24].

In addition, slice notations have useful defaults. The default for the first number is zero, and the default for the second number is size of the list being sliced. For instance, userAge[ :4] gives you values from index 0 to index 4-1 while userAge[1: ] gives you values from index 1 to index 5-1 (since the size of userAge is 5, i.e. userAge has 5 items)."

I'm not sure where they are getting the '5 - 1' if the original example had only index 0 - 4 (despite that meaning there are five items in the list). Is this a "rule change" or have they changed the index numbers from 0 to 4, to 1 to 5? I know the '5 - 1' means you would go back to index 4 due to the "end exclusive" they mention above, but don't you need the item there before you can minus it? In the original example, there is no 5th index (though there are 5 items on the list)...

Needless to say, I am very confused! Haha.

Thanks in advance for your help!

Jane. x

Jane Smith
  • 11
  • 4
  • `userAge[1: ]` is a slice starting at index 1 (explicitly written) and ending at index 4 in this particular case (length is 5, default for an unspecified end index is length-1). It's not clear why you think that anything different is happening here. – jasonharper Jan 29 '19 at 21:25
  • No, there is no change to the indexing method, that always starts from 0. Think of it as: the first part of the slice is the first index to include, the second part is the first index after that to *not* include. You seem to be thinking of it as specifying the first and last indices to include, which is causing the confusion. – Robin Zigmond Jan 29 '19 at 21:26
  • When slicing `userAge[1:]`, it's getting everything from the *2nd* element all the way to the last one. – Victor Valente Jan 29 '19 at 21:31
  • I've always found the [official Python tutorial](https://docs.python.org/3/tutorial/index.html) more than good enough at explaining these kinds of things. The section on [strings](https://docs.python.org/3/tutorial/introduction.html#strings) contains a discussion of slices. – John Y Jan 29 '19 at 21:42
  • @VictorValente - So, their note "the item at the end is always excluded" is not applicable in this case? – Jane Smith Jan 29 '19 at 22:00
  • @JohnY - Thank you for the link! I will check that out. Just trying to figure out what this author is trying to impart in this section. I have a lot to learn about programming languages etc and unfortunately, this is just the place I decided to start. Haha! – Jane Smith Jan 29 '19 at 22:03
  • @Jane Smith Oh, I see why you would get confused. It refers to the `[start:end]` notation. In this case the item at the index "end" is excluded. I think a better way to look at this is like the mathematical notation of intervals. A slice [start:end] in Python is equivalent to the [3, 8) interval, that would be all numbers between 3 and 8, including 3 and excluding 8. – Victor Valente Jan 30 '19 at 12:40
  • @Victor Valente Okay. So, I understand that when asking the interpreter to provide 'userAge[1:]' we are asking what all items come after index 1 on our original list (and that this is without the exclusion rule too), right? What I don't understand from the original extract is, if index 0 = 21, index 1 = 22, index 2 = 23, index 3 = 24, and index 4 = 25 --- where do they get index 5 - 1 from, when there is no index 5 in the original example? (I assumed something like that would bring up an error message?) Sorry. That 5 - 1 is really tripping me up. Lol. J x – Jane Smith Jan 31 '19 at 23:20

3 Answers3

1

Well, there's quite a lot of misleading explanations in this extract.

Regarding default values for slicing – forget the indexes, in "human" interpretation:

  • data[x:] – slice starting from index x all the way till the end
  • data[:x] – slice starting from the very beginning and up to x-th element

Reason reason they're telling about 5 - 1 is because second value for slicing is exclusive, i.e. to explicitly slice till the end of array of length N, you're writing [:N], but last element will have index N-1 – exactly because indexing starts at 0, but element count starts from 1.

Slam
  • 8,112
  • 1
  • 36
  • 44
0

When slicing userAge[1:], you get everything from the 2nd element all the way to the last one.

userAge[1:] = [22, 23, 24, 25]

Victor Valente
  • 761
  • 9
  • 24
0

Slicing can be explained like this.

a[first:last]#items goes at first to last-1
a[first:]#items goes from first to the rest of the array
a[:last]#items from the beginning to the end-1
a[:]#copy of the whole array.

For Step

a[first:last:step]#starts from first, not past last,by step.

I will give you another example, if you ask for a[:-2] and an only contains one element, you get an empty list instead of an error.

So, in this when we use `userage[1:], everything starts from 2nd element.

Balaji MJ
  • 21
  • 3