1
my_list = ['service', 'confidential']

path_list = ['/Users/id/work/service/number', '/Users/id/work/pager/duty', '/Users/id/work/rake/confidential', '/Users/id/work/service/number/items', '/Users/id/work']

Wanted to print only the following elements of path_list list.

  1. /Users/id/work/service/number
  2. /Users/id/work/rake/confidential
  3. Users/id/work/service/number/items

I tried:

[print(i) for i in path_list if i in my_list] and

for i in path_list:
     if i in my_list:
         print(i)

Both the options aren't working, where am I going wrong ?

Chel MS
  • 386
  • 1
  • 10

3 Answers3

1

Try with any:

[print(i) for i in path_list if any(x in i.split('/') for x in my_list)]

Output:

/Users/id/work/service/number
/Users/id/work/rake/confidential
/Users/id/work/service/number/items

The more efficient way is still:

for i in path_list:
     if any(x in i.split('/') for x in my_list):
         print(i)
U13-Forward
  • 69,221
  • 14
  • 89
  • 114
  • Wow, that's fast. Thank you.. Could you please show me, how to construct the list comprehension for it ? – Chel MS Sep 02 '21 at 08:00
  • Thanks a lot, since my reputation is less than 15, I cant upvote or accept the answer at this moment – Chel MS Sep 02 '21 at 08:02
  • Just a heads up: using a list comprehension if you don't want to build a list is considered wasteful. Also, this will print a path that contains `'confidentiality'`, for example. – timgeb Sep 02 '21 at 08:06
  • 1
    @timgeb Edited mine – U13-Forward Sep 02 '21 at 08:09
  • `match_pattern = [print(i) for i in path_list if any(x in i for x in my_list)]`, this way, I can capture the matched items into another list, right ? – Chel MS Sep 02 '21 at 08:13
  • @ChelMS Nope, you would have to use `match_pattern = [i for i in path_list if any(x in i.split('/') for x in my_list)]`, otherwise it would be a list of Nones – U13-Forward Sep 02 '21 at 08:14
  • I used `match_pattern.append(i)`, it worked, thanks for the alternative suggestion. – Chel MS Sep 02 '21 at 08:20
1

you forgot to run loop on my_list.

try this:

[print(i) for i in path_list for j in my_list if j in i]
# /Users/id/work/service/number
# /Users/id/work/rake/confidential
# /Users/id/work/service/number/items
I'mahdi
  • 23,382
  • 5
  • 22
  • 30
  • My bad, yes.. U12-Forward also pointed out the same, thanks a lot. – Chel MS Sep 02 '21 at 08:01
  • Just a heads up: using a list comprehension if you don't want to build a list is considered wasteful. Also, this will print a path that contains `'confidentiality'`, for example. – timgeb Sep 02 '21 at 08:05
1

I'm using this answer to split the paths into their components, the rest is straight forward.

import os

def split_dirs(path):
    normed = os.path.normpath(path)
    dirs = normed.split(os.sep)
    return [d for d in dirs if d]

Demo:

>>> split_dirs('/Users/id/work/service/number')
['Users', 'id', 'work', 'service', 'number']
>>> split_dirs('/////Users//////id/work/service/number')
['Users', 'id', 'work', 'service', 'number']

Solution:

my_list = ['service', 'confidential']    
path_list = ['/Users/id/work/service/number', '/Users/id/work/pager/duty', '/Users/id/work/rake/confidential', '/Users/id/work/service/number/items', '/Users/id/work']

for path in path_list:
    if any(word in split_dirs(path) for word in my_list):
        print(path)    

Output:

/Users/id/work/service/number
/Users/id/work/rake/confidential
/Users/id/work/service/number/items
timgeb
  • 76,762
  • 20
  • 123
  • 145