0

I want to use a list comprehension that returns the filenames of all files in a list of dirs. I've written the following list comprehension which fails since d is not defined at the time of os.listdir(d) on the first iteration. How can I restructure this list comprehension such that it works?

[f for f in os.listdir(d) for d in dirs if os.path.isfile(os.path.join(d, f))]
NameError: global name 'd' is not defined
  • Check this out: http://stackoverflow.com/q/3766711/198633. The `for` expressions have to be in "reverse" order for a nested list comprehension – inspectorG4dget Jun 08 '15 at 09:55

2 Answers2

2

You need to order your for loops in the same order you'd nest them; you have them swapped. Move the for d in dirs part to the front:

[f for d in dirs for f in os.listdir(d) if os.path.isfile(os.path.join(d, f))]

If it helps, write out the loops as regular for statements first:

for d in dirs:
    for f in os.listdir(d):
        if os.path.isfile(os.path.join(d, f)):
            # append f

and just join the lines and remove the : colons to create the list comprehension order.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

You have the logic in reverse

[f for d in dirs for f in os.listdir(d)  if os.path.isfile(os.path.join(d, f))]

Which is the same as:

fles = []
for d in dirs:
    for f in os.listdir(d):
        if os.path.isfile(os.path.join(d, f)):
            fles.append(f)
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321