Write Pythonic Code Like a Seasoned Developer Transcripts
Chapter: Foundational Concepts
Lecture: String formatting

Login or purchase this course to watch this video and the rest of the course contents.
0:01 Let's talk about string formatting
0:02 and building up strings from fundamental values.
0:05 Over here in PyCharm we have two variables,
0:07 a name and an age, Michael and 43.
0:10 We'd like to create the string "Hi, I'm Michael and I am 43 years old",
0:13 given whatever values those variables have.
0:16 If you are coming from some languages like say C# or Javascript,
0:20 you may try to go do something like this,
0:22 you might say, "Hi", so if we try to run this, it's actually going to crash,
0:27 you can see PyCharm is even pointing that out,
0:30 it says there is something wrong with this age
0:32 and this string concatenation here,
0:34 boom, crash, cannot convert integer to string implicitly.
0:37 So this version is obviously not Pythonic, right,
0:40 the deal is Python is not going to implicitly convert that
0:44 to a string for us so we could say "crash, don't do this".
0:48 There is some other ways to do this, we could come down here
0:51 and say if it's not going to implicitly convert this to a string, we can do that.
0:55 Now, this actually works.
0:57 We are done! Not really, we are writing bad Python code,
1:00 when we write this, so this works, but not Pythonic at all.
1:06 So, another way that we can do this is we can use a format string,
1:11 so I can come down here and say, we are going to put a string
1:14 and here we are going to put a number and I'll use "d" for integer,
1:19 and then I can do a % format here and give it a tuple,
1:24 so name and age, now format that in a little there, now if we run it,
1:27 you can see exact same text.
1:30 So this is probably Pythonic, this is very common,
1:34 but it's also an older format, it has a lot of limitations,
1:36 so for example, if I was giving the age
1:41 but the age was presented to me as actually a string, well, then this crashes.
1:47 What's on line 13 is not bad and is used quite widely,
1:51 it does have some problems.
1:53 For example, you have to very carefully know what the type is,
1:55 so I could do my "%d" with age because that was a number,
1:59 but if it happens to be that it's just a string that represents a number,
2:03 or could be converted to a number, well, again, a crash.
2:07 So there is a new, more modern style that works in Python 2 and in Python 3,
2:11 I am going to decree this style to be Pythonic,
2:14 so if we take the same code and I'm going to come here and say
2:17 "I would like to just put whatever it's specified first here,
2:20 whatever is specified second there,
2:22 and do whatever you need to do to format them",
2:25 here we go, we can do it like this,
2:27 so "Hi I'm Michael, I am 43 years old",
2:29 and it doesn't matter, let's comment this out for a moment
2:32 it doesn't matter if this is a tuple, it doesn't matter if this is a string,
2:39 it didn't even matter if it's an object, right,
2:41 anything you want can go in there
2:43 and you'll get the best string representation that you are going to get.
2:46 OK, so that's nice, really like that, but of course,
2:49 with this style we do get more flexibility here,
2:53 I didn't put numbers in here but you can say things like
2:56 I would actually like the second, this is zero based,
2:58 the second element to appear first,
3:00 and the first item to appear second like this,
3:03 so "Hi I'm 43, my name is Michael", I can even say something like
3:07 "yeah, {1}" and repeat them, right, so that's excellent.
3:10 So I think that this style, which works well in both versions of Python
3:14 is really the preferred way to do string formatting.
3:17 However, we can go farther,
3:20 suppose I have a dictionary here and it has a day called Saturday
3:24 and an office called home office,
3:26 and I'd like to take those pieces of information and say:
3:28 "On Saturday I was working in my home office."
3:31 So we could go and do something like this,
3:33 we could say "print" and let's just say we are going to put some kind of item here,
3:37 and some kind of item here.
3:39 Now I could use the format you see above
3:40 and just pull the items out of the dictionary
3:42 but I can actually say "there is a key in the dictionary called day,
3:45 and a key in a dictionary called office",
3:48 now I would like to just project this dictionary into that string,
3:51 and so I can say "format" and then do
3:53 the keyword unpacking of the dictionary like so,
3:56 on Saturday, I was working in my home office,
3:59 so not only do you get more safety around the type you get a lot more flexibility.
4:04 You see, you can have additional data in the dictionary
4:07 but if for some reason one of them is missing, if it's like this,
4:11 well that's going to crash because it's going to say
4:13 well, there is no office here, right,
4:15 so you have to have at least values you are working within a dictionary
4:18 but they can have more.
4:19 Now we can take this once step farther,
4:22 and I can't show it to you running because I am running Python 3.5,
4:25 but in Python 3.6 they have taken this idea and said this is a great idea,
4:28 if we could come down here, let's take this version,
4:34 so great idea, if I already have like a name, and an age
4:39 I could come down here and use keyword values,
4:43 like so and get this to run, right,
4:45 "Hi, I'm Michael I'm 43", kind of like unpacking our dictionary,
4:48 but in Python 3.6 they said you know,
4:50 this is such a common thing,
4:52 we would like to just grab the variable called name
4:55 and grab the variable called age and put it in the string, without format.
4:58 So if we had just an f right here,
5:00 then Python itself would actually pull name and age
5:03 out of whatever namespace it happens to be in.
5:07 Now you can see this is an error because it doesn't work,
5:10 in Python 3.5, but that's coming
5:12 in the next release of Python, which is awesome.
5:15 All right, so let's review.
5:17 The first sort of naive version of printing out this string
5:20 we are just going to concatenate them,
5:22 that works well with strings but not with non-strings,
5:25 so our age caused the crash, that was definitely not the way to do it,
5:28 we could explicitly convert that age to a string,
5:31 this is definitely not Pythonic, this is absolutely not Pythonic,
5:35 but it does print put "Hi, I'm Michael I'm 43 years old",
5:38 we can use the percent format style
5:40 where we have "%s", "%d", "%f", that kind of thing,
5:43 but it's restricted only formatting output for integers, floats,
5:48 under the "%d" and then strings under the "%s".
5:52 Anything really that can be converted to a string for those.
5:54 But you kind of have to know the format, that's not perfect to my mind.
5:58 Some people say they prefer the percent version
6:00 because there is fewer characters to type,
6:02 and that somewhat depends on your editor
6:05 I mean you do have to say ".format" instead of percent,
6:08 in PyCharm you type ".f" and hit Enter, right,
6:11 so you type about the same number of characters,
6:15 so here are the more Pythonic versions in my opinion.
6:17 The first version, we used .format(name, age)
6:21 and then we just put blank curly braces open/close curly braces,
6:24 no numbers to say that the first item here,
6:27 the second item there and so on,
6:28 we have of course the extra flexibility to say
6:31 "we'd like to reorder those and number them in the string",
6:34 if we have a dictionary so we can actually project it by key into the string
6:37 or we could even use keyword arguments on our format
6:40 to accomplish the same thing, which is really nice
6:42 because here we have a 1 and zero on a complex strings
6:46 you might have many of these little indices or whatever,
6:48 into your arguments and those are hard to maintain.
6:50 Whereas keyword arguments are really clear
6:54 what goes into which part of the string.
6:56 Finally, in Python 3.6 coming soon,
6:58 there is going to be what's called string interpolation,
7:01 where you put an "f" (format) in front of the string
7:03 that will automatically grab the data straight out of the variables.