Фильтрация списка на основе строки списков - PullRequest
0 голосов
/ 30 марта 2019

У меня есть два списка (список имен и список путей), и я хочу использовать их для создания третьего списка, элементами которого являются пути, не содержащие имен из списка имен:

names = ['name_1', 'name_2', 'name_3', 'name_4', 'name_5']
paths = ['dataset/name_1/00000003.jpg',
         'dataset/name_2/00000001.jpg', 
         'dataset/name_3/00000000.png', 
         'dataset/name_4/00000002.jpg',
         'dataset/name_5/00000000.jpg', 
         'dataset/name_6/00000002.jpg']

результирующий список из двух приведенных выше списков должен быть

['dataset/name_6/00000002.jpg']

Я достиг этого путем:

check = []
for path in paths:
    exist_boolean = any([path.__contains__(x) for  x in names])
    check.append(exist_boolean)

check_final = [not i for i in check] 
list(compress(paths, check_final))

Это излишнее убийство, есть ли элегантный способ сделать, чем уродливая логика, которую я пришелс?

Ответы [ 4 ]

2 голосов
/ 30 марта 2019

Вы можете использовать список-понимание:

[x for x in paths if all(y not in x for y in names)]

Код

names = ['name_1', 'name_2', 'name_3', 'name_4', 'name_5']
paths = ['dataset/name_1/00000003.jpg',
         'dataset/name_2/00000001.jpg', 
         'dataset/name_3/00000000.png', 
         'dataset/name_4/00000002.jpg',
         'dataset/name_5/00000000.jpg', 
         'dataset/name_6/00000002.jpg']

list3 = [x for x in paths if all(y not in x for y in names)]
# ['dataset/name_6/00000002.jpg']
1 голос
/ 30 марта 2019

Вот как я это сделал:)

names = ['name_1', 'name_2', 'name_3', 'name_4', 'name_5']
paths = ['dataset/name_1/00000003.jpg',
         'dataset/name_2/00000001.jpg',
         'dataset/name_3/00000000.png',
         'dataset/name_4/00000002.jpg',
         'dataset/name_5/00000000.jpg',
         'dataset/name_6/00000002.jpg']
newpath = paths
nopath = []
for path in paths:
    for name in names:
        if name in path:
            nopath.append(path)

for path in nopath:
    newpath.remove(path)
0 голосов
/ 30 марта 2019

Может быть, вы хотите попробовать один из следующих

regex = re.compile(r'^(?!.*({}))'.format("|".join(names)))
list3 = list(filter(regex.search, paths))
# ['dataset/name_6/00000002.jpg']

# Perform test performance in list names 10k items and 15k items in paths
In[1]: %timeit list(filter(regex.search, paths))
15 ms ± 314 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [2]: %timeit [x for x in paths if all(y not in x for y in names)]
41.4 ms ± 903 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
0 голосов
/ 30 марта 2019

Используйте функцию any здесь;с пониманием списка: -

>>> names = ['name_1', 'name_2', 'name_3', 'name_4', 'name_5']
>>> paths = ['dataset/name_1/00000003.jpg',
...          'dataset/name_2/00000001.jpg', 
...          'dataset/name_3/00000000.png', 
...          'dataset/name_4/00000002.jpg',
...          'dataset/name_5/00000000.jpg', 
...          'dataset/name_6/00000002.jpg']
>>> 
>>> [ j for j in paths if not any(n in j for n in names)]
['dataset/name_6/00000002.jpg']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...