Jaki jest najlepszy sposób sprawdzenia, czy niektóre słowa w kombinacji przy użyciu operatorów logicznych (or, and) znajdują się na liście ciągów?

Załóżmy, że masz listę ciągów:

list_of_str = ['some phrase with word1','another phrase','other phrase with word2']

Mam dwa przypadki 1) i 2), w których chciałbym uzyskać ciągi zawierające lub niezawierające niektórych słów. jednak wolałbym nie powtarzać tego, co robię teraz if 'word1' not in i and 'word2' not in i and 'word3' not in i

Chciałbym otrzymać 1)

list_1 = [i for i in list_of_str if 'word1' not in i and 'word2' not in i and 'word3' not in i]
output: ['another phrase']

I 2)

list_2 = [i for i in list_of_str if 'word1' in i or 'word2' in i or 'word3' in i]
output: ['some phrase with word1', 'other phrase with word2']

Okazało się, że mogę to zrobić dla 2), ale nie mogę użyć all dla przypadku 1)

list_2 = [i for i in list_of_str if any(word in ['word1','word2','word3'] for word in i.split())]
output: ['some phrase with word1', 'other phrase with word2']

Czy jest to również najbardziej efektywny sposób robienia rzeczy?

1
AnarKi 2 kwiecień 2020, 12:53

3 odpowiedzi

Najlepsza odpowiedź

Możesz użyć:

words = ['word1', 'word2', 'word23']

list_1 = [i for i in list_of_str if all(w not in i for w in words)]

list_2 = [i for i in list_of_str if any(w in i for w in words)]
2
kederrac 2 kwiecień 2020, 09:58

Myślę, że to dobry przypadek użycia alternacji wyrażeń regularnych, jeśli liczy się wydajność:

>>> import re
>>> words = ['word1', 'word2', 'word23']
>>> regex = re.compile('|'.join([re.escape(w) for w in words]))
>>> regex
re.compile('word1|word2|word23')
>>> list_of_str = ['some phrase with word1','another phrase','other phrase with word2']
>>> [phrase for phrase in list_of_str if not regex.search(phrase)]
['another phrase']
>>> [phrase for phrase in list_of_str if regex.search(phrase)]
['some phrase with word1', 'other phrase with word2']
>>>
1
juanpa.arrivillaga 2 kwiecień 2020, 10:03

Jeśli myślisz o tym w zestawach , potrzebujesz zdań z tej listy, w których zestaw wyszukiwanych słów i zestaw słów w zdaniu są rozłączne lub przecinają się.

Na przykład.:

set('some phrase with word1'.split()).isdisjoint({'word1', 'word2', 'word23'})
not set('some phrase with word1'.split()).isdisjoint({'word1', 'word2', 'word23'})
# or:
set('some phrase with word1'.split()) & {'word1', 'word2', 'word23'}

Więc:

search_terms = {'word1', 'word2', 'word23'}
list1 = [i for i in list_of_str if set(i.split()).isdisjoint(search_terms)]
list2 = [i for i in list_of_str if not set(i.split()).isdisjoint(search_terms)]
1
deceze 2 kwiecień 2020, 10:09