'How can I find patterns when applying a filter to a list?

I am applying a filter to find a list of folders that comply some conditions.

For example, when I have several folders with names like a_1_1_1 ,a_2_2_2 I do

folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)) and x[1]=='_', os.listdir(d)))

where d is the base folder.

Then if I have some folder with several subfolders with names like ab_1_1_1 and ab_1_2_3 I have to change the above with

folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)) and x[2]=='_', os.listdir(d)))

This is cumbersome and not general , so I would like to replace the x[n]=='_' condition with something more general' For example list folders that have three _ with numbers after the _.

How can I introduce this pattern to the expression? (I heard regular expressions but I don't know how)



Solution 1:[1]

One implementation could be to use split on "_" and see if what you get is length 4 all (except the first split part) are numbers using all:

out = list(filter(lambda x: os.path.isdir(os.path.join(d, x)) and len(x.split('_'))==4 and all(i.lstrip('-').isdigit() for i in x.split('_')[1:]), os.listdir(d)))

But I think it might be more readable to write it using a for-loop instead of filter:

out = []
for x in os.listdir(d):
    if os.path.isdir(os.path.join(d, x)):
        s = x.split('_')[1:]
        if len(s) == 3 and all(i.lstrip('-').isdigit() for i in s):
            out.append(x)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1