Os.scandir question

By Bart via Discussions on Python.org at 20Mar2022 21:51:

The following code works:

import os

txtFiles = [f.name[:-4] for f in os.scandir() if f.name.lower().endswith('.txt')]
mp4Files = [f.name[:-4] for f in os.scandir() if f.name.lower().endswith('.mp4')]

However the following code does not work:

import os

dircontent = os.scandir()

txtFiles = [f.name[:-4] for f in dircontent  if f.name.lower().endswith('.txt')]
mp4Files = [f.name[:-4] for f in dircontent  if f.name.lower().endswith('.mp4')]

You do not say what, specificly, “does not work” actually means i.e.
what you expected and what you actually got. But I have a good guess.

This will be because os.scandir() returns a generator (not a list),
which yields the entries in the directory. So your txtFiles list
comprehension consumes the iterator. The mp4Files list comprehension
is then using an empty iterator and finds nothing.

Is this bourne out by the contents of txtFiles and mp4Files if you
print them?

The usual approach when you get an iterator you need to use more than
once it to consume it immediately into a list, then use the list from
there on:

dircontent = list(os.scandir())

That isn’t always appropriate (for example very big generators or ones
where consuming the entire generator will be unduly expensive) but it is
the normal situation.

Cheers,
Cameron Simpson cs@cskk.id.au