Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Concatenating, Indexing, and Slicing

00:00 In the previous lesson, you learned all about creating strings and writing out string literals. In this lesson, you’re going to learn about concatenation, indexing, and slicing, three basic string operations.

00:14 Concatenation joins two strings together, indexing gets a single character from a string, and slicing gets several characters from a string at once.

00:26 Let’s start with concatenation. To combine, or concatenate, strings, you use the + (plus) operator. You’re adding one string to another, and that concatenates them. In this example, string1, "abra", and string2, "cadabra", are tied together, or concatenated, into magic_string by assigning magic_string to string1 + string2. Let’s try out some examples in the interactive window.

00:55 Okay. Here in the interactive window, create the two strings by assigning "abra" to one and "cadabra" to the other, and then create a third variable, magic_string and say string1 + string2. That will concatenate them together into abracadabra. Great. Let’s feed it something with names.

01:20 Say you had a first_name of "Arthur" and a last_name of "Dent", and you wanted to create a full_name. That full_name, though, needs a space in the middle of it. Well, you can do that through concatenation also.

01:33 You would add the first_name to a string that has a single space (" ") in it and then also concatenate that with last_name. So here, we’re adding first_name, " ", and last_name. That should create the full_name Arthur Dent.

01:53 Now I’m going to have you look at indexing. Each character in a string has a numbered position. It’s called an index. Individual characters can be accessed by using the index. You place the index number inside of a pair of square brackets ([]) after the string, something like this.

02:11 This would be index 3 and return that character. What may seem a little different is the index count starts with 0. Most programming languages do this, and it is really common to have what’s called an off-by-one error because the thought in your head might be, oh, the counting should start with 1, whereas most often, it actually starts with 0.

02:36 In the case of my string with index 3, that would be the fourth position. Let me show what this looks like. Let’s say you had the string "apple pie" with a space in between. That string is made up of nine characters.

02:51 The indexes start from 0 and go up to 8. So to access the first character, you would use index 0. Let’s say you wanted the fifth character. Well, that would be index 4, and so forth.

03:04 Let’s try this out in the interactive window.

03:12 If you were to use an index of 1, that won’t return the first character. It returns the second. The first character—again, because everything is a 0 index—You’d have to use 0. And this whole string is nine characters, so to grab the last one, it would be 8. To get the space in the middle would be 5.

03:36 If you try to index beyond the range—let’s say you use 9it will tell you that. It’ll say the string index is out of range in IndexError.

03:51 Strings also have negative indices. The last character in a string has an index of -1. So in the case of "apple pie", that would be the "e" of "apple pie". To grab the second to last character, you would enter in -2, and so on.

04:07 Just like with positive indices, Python raises an IndexError if you try to access a negative index less than the index of the first character of the string—in this case, -9if you go lower than that, say something like -10.

04:22 Negative indices may not seem useful at first, but sometimes they are a better choice than a positive index. Let me have you check that out in the interactive window.

04:36 So for negative indices, such as the last character in the string, you can start with -1. And to get that first character, that would be -9.

04:49 What if you go beyond? Again, you get the out of range. This may not seem useful at first, but we’ll come up with some handy things for using negative indices here in a second.

05:03 One way that you could try to access the last character of a string might be to use the len() function. You might have some user input as a string.

05:15 Let’s just say somebody had typed "Hello World" into your system, and you wanted to grab that "d" or that last character. You could say, okay, well, the final index is equal to the length of user_input, so find the length of the string and then subtract 1 from it. You know, give me that value. So that in this case, for final_index, that’s 10. Okay.

05:44 So the last_character would be user_input[final_index]. Again, you could see that this might be much easier to do with just having -1. It’s going to take a lot less typing.

06:05 What if you had a string, like you did before, of "apple pie", and you wanted to return a string that was just the flavor of the pie, just the word "apple"? Well, this is one way you could do it, but you can see this might be a bit of a pain. We got there, but that’s a lot of indexing and concatenation.

06:29 That’s where slicing comes in.

06:33 You can extract a portion of a string, called a substring, by inserting a colon (:) in between two index numbers set inside the square brackets like this. So in this case, let’s say you wanted to return just the flavor of the pie.

06:50 You could put dessert[0:5], and that will capture just the word "apple". A slice starts with the character at the first index and goes up to, but does not include, the character at the second index.

07:06 So, in the case of [x:y], it starts at the character at index x and goes right up to, but does not include, the index at y.

07:20 In fact, it kind of behaves a little bit more like boundaries around the characters. So, let’s say we had a fig pie. You could see the boundaries starting there, where if you wanted to capture the flavor of that pie, a fig, you would have 0 up to 3.

07:38 So, for "fig pie", the slice of [0:3] returns the string "fig", and the slice [3:7] would return the string of a space and the word "pie".

07:54 So let’s make a new dessert, a "fig pie". So again, if you wanted to return just the flavor of the new dessert, you could go from index 0 up to index 3, and that would return the slice of just "fig".

08:10 If you went from index 3 up to index 7, that would return " pie". An interesting thing happens if you go over the number.

08:21 Let’s say you went to [3:9]. Even though that’s beyond that, it’s okay. It doesn’t create the same kind of error that you got before, where if you went over the index, it told you that it was out of range.

08:37 It’s important to note that unlike with string indexing, Python won’t raise an IndexError when you try to slice between boundaries that fall outside the beginning or the ending of a string.

08:48 So even if you went and tried to start at an index beyond that—let’s say you went from 9 to 12it simply returns what’s known as an empty string. An empty string, again, is a string that has no characters in it. It’s still a string.

09:07 It’s just doesn’t have any characters in it. It’s different from one that has a space in it.

09:15 There you can see the one space. Or let’s say you had, like, several spaces in there.

09:25 The spaces still count.

09:31 Negative slicing works by the same rules. Again, a slice starts at x and includes that character and goes up to, but does not include, the character at index y. So in the case of "fig pie", -7 up to -4 would capture that first word.

09:48 Now there’s some interesting things that you can do. Like you can see here, how would you capture all of that string of "fig pie"? Well, there’s a couple ways around it.

10:02 For negative indexing, let’s say you started at -7, which would be all the way at the very first boundary, and you went up to -4. That would return, again, just fig the slice of "fig". Now, you might be thinking, well, how do you go all the way up to the end?

10:24 Would you go from -7 to 0, you know, because -1 is going to get up to the "i" of "pie", but not include the "e". So would you use 0?

10:37 Well, no. That returns an empty string, and the reason for that is, if you might remember, 0 is already used as an index. 0 is the first character.

10:47 So there is a way around this. It’s to omit the second index. And that means to actually go to the end of the string.

11:00 So there’s three different ways that you can omit an index. If you omit the first index, it will start with the very first character of the string from the beginning of it and work normally, going up to, but not including, the second index number.

11:17 Doing a slice of [:5] will return just "apple".

11:24 If you omit the index after the colon, it’s going to end with the last character. So, you can see here, dessert[6:] would grab just the word "pie".

11:36 If you omit both indexes, that returns the whole string, and you can see that in the bottom example. So that’s an option is that you can omit the indexes to get either the beginning of the string or the end of the string, or in the case of removing both indices, you return the whole string.

11:59 Okay. I’m going to try a couple of these out in the interactive window, working again with new_dessert. If you go from 0 and put a :, it will capture all the way to the end. If you want just the word "pie", you could start at index 4 and add the :.

12:15 And that would grab just that last word. If you omit the first, again, it will start from the beginning. So if I went from [:4], that would return "fig ". Actually, I just wanted the word "fig", so that would be [:3].

12:32 And then the last technique that you learned was that if you have just a : that will return the whole string.

12:44 So to wrap this lesson up, one last thing that you need to know is that strings are immutable, which means that you can’t change them once they’ve been created.

12:53 Let’s say you assigned "boil" to the variable word, and then you went in and tried to change the character that’s at index 0, which is the first letter. And you’re like, okay, let’s reassign the first letter to "f". You’ll see a TypeError: 'str' object does not support item assignment.

13:14 You can’t reassign a letter inside there.

13:20 So, to alter a string, you actually have to create a new one, and that can be done through reassignment. This will actually create a new string object. So, one way to accomplish what we were trying to do a moment ago: I want include the last three letters of word—in this case, it would be "oil" to change word from "boil" to "foil"and concatenate that to the letter "f". But what’s unique here is you’re reassigning word, so that’s creating a whole new object—in this case, removing the previous one.

13:56 You have to actually do it through a reassignment statement.

14:02 It’s time for you to practice what you’ve learned this lesson. Here are a few review exercises to try. create a string and print its length using the built-in len() function.

14:13 Try creating a couple strings and concatenate them, and then print the resulting string. Create two strings, use concatenation to add a space in between them, and print out the result.

14:27 Print the string "zing" by using slice notation to specify the correct range of characters in the string "bazinga".

14:38 Next up, it’s time to start manipulating strings with methods.

Avatar image for Andres Rengifo

Andres Rengifo on July 5, 2023

It would be nice to have a short video with the explanation of the answers for the exercises at the end of the video.

Avatar image for rubynicholls

rubynicholls on Feb. 9, 2024

Trying to understand why I’d use indexing, any ideas?

Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on Feb. 12, 2024

@rubynicholls Think of indexing as a way to speed up searching for a particular element in a sequence. Numeric indices are like page numbers akin to an index at the end of a book. One example would be finding the middle element to cut a sequence in two.

Avatar image for rubynicholls

rubynicholls on Feb. 12, 2024

Ok thanks Bartosz, so selecting a subset of data perhaps?

Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on Feb. 12, 2024

@rubynicholls This reminds me of a time when I was trying to wrap my head around arrays in programming. At that time, I asked myself why anyone would use an array in the first place. Once it clicked for me, I couldn’t imagine programming without them anymore.

Indexing is kind of similar. It’s difficult for me to give you specific examples because indexing is so ubiquitous that you practically stop thinking about it. However, let me try.

In practice, you don’t usually refer to an element by a literal index, such as “the 4th element,” but use a variable that goes through all indices irrespective of how many elements your sequence contains. That way, you can ensure that all elements get updated in one way or another. Here’s an example:

>>> fruits = ["apple", "banana", "orange"]
>>> for i in range(len(fruits)):
...     fruits[i] = fruits[i].title()
>>> print(fruits)
['Apple', 'Banana', 'Orange']

Here, you iterate over a list of fruit names by index and format each string using title case.

Become a Member to join the conversation.