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


Talk Python's Mastodon Michael Kennedy's Mastodon