Generating a filtered list with for and if on the same line

The project I am working on has folders of 3 different types on its data directory: green, yellow and red. There are many folders of each data type and their names start with the respective color, as in: “RED_folder1”. I came upon the following code, that has the objective of generating a list containing all folders of a specific type.

Define target directory:

directory = '/project/data'

Generate list of folders of the red type:

red_folders = [k for k in os.listdir(directory) if os.path.isdir(os.path.join(directory,k)) and 'RED_' in k[:len('RED_')]]

I feel weird about this code because it is creating a list of the k entries in os.listdir(directory) that fit the given criteria, but the criteria themselves are also dependent on k. In which order is this line of code handled? Is it correct to assume that whole k in os.listdir(directory) list is created and then the if statement is considered and inapropriate entries discarted?

My confusion might come from not knowing exactly in which order python handles multiple operators on the same line, so a short explanation on that would also be nice.

Answer

An equivalent code for your list composition:

for k in os.listdir(directory):
     if os.path.isdir(os.path.join(directory,k)) and 'RED_' in k[:len('RED_')]:
           red_folders.append(k)

First a list of directories is generated. Then var k iterates over each element of sequence. The If statement is executed. If condition is found to be true, then the k is appended. Now in your list composition the same mechanism is working. The only difference is that instead of red_folders.append(k), a whole new list is generated and then is given the name red_folders.

red_folders=new_list_created_by_list_composition

If you have any queries or not satisfied with the answer, then please tell me