У меня есть большой список, который выглядит примерно так:

entries = ["['stuff']...other stuff", "['stuff']...stuff", "['stuff']...more stuff", ...]

Я хочу удалить все элементы списка, которые не содержат слова «другие» или «вещи».

Я попробовал это, но он не удаляет все элементы, которые мне нужны (только некоторые в конце):

for e in entries:
    if 'other' or 'things' not in e:
        entries.remove(e)
print entries

Что я делаю не так?

0
curious_cosmo 29 Авг 2017 в 02:26

3 ответа

Лучший ответ

Вы не должны удалять элементы из списка во время итерации по нему. Кроме того, ваше условное утверждение не соответствует тому, что вы имеете в виду: оно проверяет 'other' на достоверность и только 'things' на сдерживание. Чтобы исправить это, используйте and с двумя отдельными in проверками.

Если список не очень большой, вы можете просто использовать его для восстановления:

entries = [e for e in entries if "other" not in e and "things" not in e]

В противном случае переходите от конца списка к началу и удаляйте элементы по индексам.

for i in range(len(entries)-1, -1, -1):
    if "other" in entries[i] and "things" in entries[i]:
        del entries[i]
1
Eugene Yarmash 28 Авг 2017 в 23:46

Как уже отмечали другие, в вашей версии есть три основные проблемы:

for e in entries:
    if 'other' or 'things' not in e: #or returns first truthy value, and `if other` is always true.  Also, you need and, not or.
        entries.remove(e) #mutating the item you are iterating over is bad
print entries

Вот ваша версия, исправленная для устранения вышеуказанных проблем:

for e in words[:]: #words[:] is a copy of words, solves mutation issue while iterating
    if 'other' not in e and 'things' not in e: #want words that both don't contain 'other' AND dont contain 'things'
        print(e)
        words.remove(e)
print(words)

И вот несколько альтернативных способов сделать это:

import re

words = ['this doesnt contain chars you want so gone',
         'this contains other so will be included',
         'this is included bc stuff']

answer = list(filter(lambda x: re.search('other|stuff',x),words))
other_way = [sentence for sentence in words if re.search('other|stuff',sentence)]

print(answer)
print(other_way)
0
Solaxun 29 Авг 2017 в 00:01

Вы можете использовать выражение для понимания списка , используя all(..), чтобы проверить подстроку как:

>>> [entry for entry in entries if any(something in entry  for something in  ["other", "things"])]

Это вернет вам новый список слов, содержащих «другие» или «вещи».

0
Moinuddin Quadri 28 Авг 2017 в 23:38