Write Pythonic Code Like a Seasoned Developer Transcripts
Chapter: Generators and Collections
Lecture: Recursive generators with yield from
0:01 So we've seen how powerful and amazing the yield keyword is to build these generators.
0:06 In Python 3, there is actually a new feature that makes working with generators as well as recursive functions even better.
0:15 So over here we have some code and what it's going to do is it's going to go to some root directory
0:21 here I just grabbed the transcripts from my other class, Python Jumpstart By Building Ten Apps, and the transcripts are here in these demos folder,
0:29 and we want to just process through those, so I've written this function called get_files() and I give it a root directory,
0:36 and it returns using yield the generator that we can iterate over and print them out.
0:41 So this is pretty straightforward, we are going to go to a directory,
0:45 this will be the top level directory, and we'll say "for each item I'd like to look at it", let's build up it's full path and ask: "is it a file,
0:51 or is it a directory?", so if it's s file we'll say "yeah, I found one of the files in this directory,
0:57 here go loop over this", but if it is itself a directory, well let's just hold off on that for a minute.
1:04 So here if I run it you can see on my Mac I have this .DS_store thing and then I have this txt file and then that's that.
1:12 So not many files. But it turns out there is subdirectories in here and maybe I want to look inside them
1:17 if I had a function that could look inside a folder, and tell you what was in it, tell you the files that are in it,
1:23 that would be awesome, I could use that, right? Well, what do I have right here, boom, so what we can do is we can use a concept called recursion
1:30 and if you are used to recursion this makes perfect sense, but if you are not, it's quite interesting and sort of mind bending,
1:37 so the idea is from within this function we are going to call the same function but with possibly, this time certainly, with different parameters,
1:45 so we are going to work our way down the directory tree until there are no more subdirectories
1:49 then we will stop calling our function but as long as there are subdirectories, we are going to be calling it like this,
1:54 Now this returns a generator of files and technically it will return like a tree of generators, of files so how do I get the files out?
2:03 Well, I could write this, "for f in files, get files" and then I could say "yield f" and so this is just the idea of recursion,
2:12 there is no special feature here, but let's just verify it works. Boom, here you go, so you can see in app 10 I've got a couple of transcripts,
2:20 in the conclusion I've got a couple of transcripts, there is quite a few files that were in subdirectories here. Lovely.
2:26 And notice we actually are printing the directory as well, I'll turn that off for a minute. So those are just the files.
2:34 So like I said, this is straight up recursion, and this is kind of not-so-great, we'd like to just say hey here are a bunch of items in a generator
2:44 and I would like to make all of those items part of my sequence, so in Python 3,
2:48 we can do this, we can say instead of just yield we can say "yield from get_files" and full_item and this is basically replacing that loop above
2:58 so we can do it in kind of a inline sequence way, let's try it again, we should get exactly the same output, boom, we do,
3:05 beautiful, so "yield from", super helpful when you are doing recursion or you want to just grab a bunch of items from some kind of generator
3:12 or set and throw them into your current set that you are trying to generate. So here you can see we are calling "get items",
3:19 it's a generator because it's using the yield keyword and we are also calling it recursively
3:24 and we are able to simplify that recursion using "yield from". So remember, this is a Python 3 only feature and in fact,
3:30 it was introduced in Python 3.3 so it doesn't even work in the early versions of Python 3. That said, if you are working in 3.3 or above,
3:39 it's a really cool way to simplify generators.