Удаление элементов из списка на основе другого списка

#python #list

Вопрос:

Как удалить элементы из списка lst1 на основе списка lst2 ?

 lst1 = ['abc__2','def__3','xyz__3','pqr__1']
lst2 = ['def','xyz','tuv']
 

за то, что я разделился, я сделал

 lst3 = [k.split("__")[0] for k in lst1]
 

для удаления я сделал

 new_list = [i for i in lst3 if i not in lst2]
 

Но таким образом я потерял оригинальность первоначального списка.

Необходимый список: new_list = ['abc__2','pqr__1']

Комментарии:

1. Это списки, а не массивы. Пожалуйста, исправьте это и ваше форматирование. Вопрос очень запутанный.

Ответ №1:

Вместо создания arr3 с разделенными значениями вы можете разделить их в разделе if при создании new_arr

 arr1 = ['abc__2', 'def__3', 'xyz__3', 'pqr__1']
arr2 = ['def', 'xyz', 'tuv']
new_arr = [i for i in arr1 if i.split("__")[0] not in arr2]
print(new_arr) # ['abc__2', 'pqr__1']
 

Ответ №2:

Здесь мы можем использовать re.search подход регулярных выражений для изучения каждого элемента в первом массиве с помощью чередования:

 arr1 = ['abc__2','def__3','xyz__3','pqr__1']
arr2 = ['def','xyz','tuv']
regex = r'^(?:'   r'|'.join(arr2)   r')'

output = [x for x in arr1 if not re.search(regex, x)]
print(output)  # ['abc__2', 'pqr__1']
 

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

 ^(?:def|xyz|tuv)
 

Ответ №3:

Превратитесь arr2 в a set для быстрого поиска:

 s2 = set(arr2)
 

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

 [x for x in arr1 if x.split('___')[0] not in s2]
 

Чтобы использовать промежуточный список arr3 , вам придется каким-то образом сохранить его в оригинале. Одним из способов были бы индексы:

 [arr[i] for i, x in enumerate(arr3) if x not in s2]
 

Другой способ-превратить arr3 в словарь вместо списка:

 d3 = {x: x.split('___')[0] for x in arr}
[v for k, v in d3.items() if k not in s2]
 

Комментарии:

1. Эй, небольшая поправка, x.split('__')[0] вы сохранили три подчеркивания.

2. @Random_Pythoneer59. Теперь это должно быть исправлено. Спасибо за улов

Ответ №4:

Ты мог бы сделать вот так:

 arr1 = ['abc__2', 'def__3', 'xyz__3', 'pqr__1']
arr2 = ['def', 'xyz', 'tuv']

new_arr = arr1.copy() #New copy of the arr1
for item in arr1:
    for item2 in arr2:
        if item.startswith(item2):
            new_arr.remove(item)

print(arr1)
print(arr2)
print(new_arr)
 

Выход:

 ['abc__2', 'def__3', 'xyz__3', 'pqr__1']
['def', 'xyz', 'tuv']
['abc__2', 'pqr__1']
 

Комментарии:

1. Вероятно, используйте startswith вместо __contains__ здесь

2. @Безумный физик Да, так лучше

Ответ №5:

Вы можете использовать для каждого цикла и метод разделения, затем цикл while и попытаться/поймать, чтобы удалить все экземпляры слова:

 arr1=['abc__2','def__3','xyz__3','pqr__1']
arr2 =['def','xyz','tuv']

for word in arr1:
  letters = word.split("__")[0]
  while True:
    try:
      arr2.remove(letters)
    except:
      break
print(arr2)
 

Результирующий результат:

 ['tuv']
 

Комментарии:

1. Это не то, что ищет ит-отдел. Они дают требуемый результат в вопросе.